给定整数N。找到最小平方自由因数。换句话说,N的因式分解应仅包含那些无平方的除数。平方自由数是不能被任何理想平方整除的数字(当然,在这种情况下,1将不被视为理想平方)。
Constraints: 2 ≤ N ≤ 106
例子:
Input : 24
Output : 3
Explanation: 24 will be represented as 24 = 6 x 2 x 2, here every factor
(6 and 2) both are square free.
Note: 24 cannot be represented as (24 = 12 x 2) or (24 = 24) or (24 = 8 x 3) because in all these factorizations, every factorization has atleast one number that is not square free i.e. 12, 24 and 8 are divisible by 4 (4 is a perfect square). Hence minimum number of square free divisors is 3.
Input : 6
Output : 1
Explanation: 6 will be represented as 6 = 6, since 6 is not divisible by any perfect square. Hence minimum number of square free divisors is 1.
先决条件: Eratosthenes筛
幼稚的方法是考虑所有可能的数字N的因式分解,然后检查每个因式分解是否存在不是平方无平方(可被某个理想平方整除)的数字。如果存在,则丢弃该分解,否则在回答中考虑该分解。在考虑了所有正确的因式分解之后,找到最小平方自由除数。
高效的方法:通过找到直至N的平方根的所有素因数(考虑到约束,最多10 3 )来构建Prime筛(使用Eratosthenes筛)。现在,考虑所有小于或等于N平方根的素数,并为每个素数找到其最大幂数N(例如24中2的最大幂为3)。现在,我们知道如果素数的幂大于N的1,则不能将其与自身分组(例如2具有24的3的幂,因此2 x 2 = 4或2 x 2 x 2 = 8不能在24的因式分解中发生,因为它们都不都是无平方的,因为它们可以被某个理想的平方整除。但是,与另一个素数(仅一次)组合的素数永远无法被任何理想平方整除。这给我们一种直觉,答案将是数量N中所有素数的最大幂的最大值。换句话说,
If prime factorization of N = f1p1 * f2p2 * ... * fnpn
where f1, f2 ... fn are the prime factors and p1, p2 ... pn are their
maximum respective powers in N. Then answer will be,
ans = max(p1, p2, ..., pn)
For e.g. 24 = 23 * 31
ans = max(3, 1) = 3
下图说明了上述算法
Let N = 24. Factorization of N can be represented in many ways and out of those we have to find that in which there are minimum divisors with each divisor being square free. Some factorizations are:
24 = 24 (24 is not square Free)
24 = 2 * 12 (12 is not square free)
24 = 3 * 8 (8 is not square free)
24 = 4 * 6 (4 is not square free)
24 = 6 * 2 * 2 (Every divisor is square free with divisor count = 3)
24 = 3 * 2 * 2 * 2 (Every divisor is square free with divisor count = 4)
Hence, appropriate answer would be 3 (24 = 6 * 2 * 2). Now if we observe carefully, we can’t group a prime factor with itself but with another prime factor. Like in this case, 2 is grouped with 3 to make 6 (square free) to reduce divisors count. Thus, answer would be maximum of maximum powers of all prime factors because we need atleast that much count to retain the condition of square free and other prime factors (whose power is not maximum) can be grouped with the prime factor with maximum power to minimize the count of divisors.
下面是上述方法的实现。在这里,我们将进行预处理以找到主要因素(使用筛分法),以便我们可以同时回答许多查询。
C++
// CPP Program to find the minimum
// number of square free divisors
#include
using namespace std;
// Initializing MAX with SQRT(10 ^ 6)
#define MAX 1005
void SieveOfEratosthenes(vector& primes)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
bool prime[MAX];
memset(prime, true, sizeof(prime));
for (int p = 2; p * p < MAX; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p
for (int i = p * 2; i < MAX; i += p)
prime[i] = false;
}
}
// Print all prime numbers
for (int p = 2; p < MAX; p++)
if (prime[p])
primes.push_back(p);
}
// This function returns the minimum number of
// Square Free divisors
int minimumSquareFreeDivisors(int N)
{
vector primes;
// Precomputing Prime Factors
SieveOfEratosthenes(primes);
// holds max of max power of all prime factors
int max_count = 0;
for (int i = 0; i < primes.size() && primes[i] * primes[i] <= N; i++) {
if (N % primes[i] == 0) {
// holds the max power of current prime factor
int tmp = 0;
while (N % primes[i] == 0) {
tmp++;
N /= primes[i];
}
max_count = max(max_count, tmp);
}
}
// If number itself is prime, it will be included
// as answer and thus minimum required answer is 1
if (max_count == 0)
max_count = 1;
return max_count;
}
// Driver Code to test above functions
int main()
{
int N = 24;
cout << "Minimum Number of Square Free Divisors is "
<< minimumSquareFreeDivisors(N) << endl;
N = 6;
cout << "Minimum Number of Square Free Divisors is "
<< minimumSquareFreeDivisors(N) << endl;
return 0;
}
Java
// Java Program to find the minimum
// number of square free divisors
import java.util.Vector;
public class GFG {
// Initializing MAX with SQRT(10 ^ 6)
static final int MAX = 1005;
static void SieveOfEratosthenes(Vector primes) {
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
boolean prime[] = new boolean[MAX];
for (int i = 0; i < prime.length; i++) {
prime[i] = true;
}
for (int p = 2; p * p < MAX; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p
for (int i = p * 2; i < MAX; i += p) {
prime[i] = false;
}
}
}
// Print all prime numbers
for (int p = 2; p < MAX; p++) {
if (prime[p]) {
primes.add(primes.size(), p);
}
}
}
// This function returns the minimum number of
// Square Free divisors
static int minimumSquareFreeDivisors(int N) {
Vector primes = new Vector<>();
// Precomputing Prime Factors
SieveOfEratosthenes(primes);
// holds max of max power of all prime factors
int max_count = 0;
for (int i = 0; i < primes.size() && primes.get(i) *
primes.get(i) <= N; i++) {
if (N % primes.get(i) == 0) {
// holds the max power of current prime factor
int tmp = 0;
while (N % primes.get(i) == 0) {
tmp++;
N /= primes.get(i);
}
max_count = Math.max(max_count, tmp);
}
}
// If number itself is prime, it will be included
// as answer and thus minimum required answer is 1
if (max_count == 0) {
max_count = 1;
}
return max_count;
}
// Driver Code to test above functions
public static void main(String[] args) {
int N = 24;
System.out.println("Minimum Number of Square Free Divisors is "
+ minimumSquareFreeDivisors(N));
N = 6;
System.out.println("Minimum Number of Square Free Divisors is "
+ minimumSquareFreeDivisors(N));
}
}
Python3
# Python 3 Program to find the minimum
# number of square free divisors
from math import sqrt
# Initializing MAX with SQRT(10 ^ 6)
MAX = 1005
def SieveOfEratosthenes(primes):
# Create a boolean array "prime[0..n]" and
# initialize all entries it as true. A value
# in prime[i] will finally be false if i is
# Not a prime, else true.
prime = [True for i in range(MAX)]
for p in range(2,int(sqrt(MAX)) + 1, 1):
# If prime[p] is not changed, then
# it is a prime
if (prime[p] == True):
# Update all multiples of p
for i in range(p * 2, MAX, p):
prime[i] = False
# Print all prime numbers
for p in range(2, MAX, 1):
if (prime[p]):
primes.append(p)
return primes
# This function returns the minimum number
# of Square Free divisors
def minimumSquareFreeDivisors(N):
prime = []
primes = []
# Precomputing Prime Factors
primes = SieveOfEratosthenes(prime)
# holds max of max power of all
# prime factors
max_count = 0
i = 0
while(len(primes) and primes[i] *
primes[i] <= N):
if (N % primes[i] == 0):
# holds the max power of current
# prime factor
tmp = 0
while (N % primes[i] == 0):
tmp += 1
N /= primes[i]
max_count = max(max_count, tmp)
i += 1
# If number itself is prime, it will be included
# as answer and thus minimum required answer is 1
if (max_count == 0):
max_count = 1
return max_count
# Driver Code
if __name__ == '__main__':
N = 24
print("Minimum Number of Square Free Divisors is",
minimumSquareFreeDivisors(N))
N = 6
print("Minimum Number of Square Free Divisors is",
minimumSquareFreeDivisors(N))
# This code is contributed by
# Surendra_Gangwar
C#
// C# Program to find the minimum
// number of square free divisors
using System;
using System.Collections.Generic;
public class GFG {
// Initializing MAX with SQRT(10 ^ 6)
static int MAX = 1005;
static void SieveOfEratosthenes(List primes) {
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
bool []prime = new bool[MAX];
for (int i = 0; i < prime.Length; i++) {
prime[i] = true;
}
for (int p = 2; p * p < MAX; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p
for (int i = p * 2; i < MAX; i += p) {
prime[i] = false;
}
}
}
// Print all prime numbers
for (int p = 2; p < MAX; p++) {
if (prime[p]) {
primes.Add(p);
}
}
}
// This function returns the minimum number of
// Square Free divisors
static int minimumSquareFreeDivisors(int N) {
List primes = new List();
// Precomputing Prime Factors
SieveOfEratosthenes(primes);
// holds max of max power of all prime factors
int max_count = 0;
for (int i = 0; i < primes.Count && primes[i] *
primes[i] <= N; i++) {
if (N % primes[i] == 0) {
// holds the max power of current prime factor
int tmp = 0;
while (N % primes[i] == 0) {
tmp++;
N /= primes[i];
}
max_count = Math.Max(max_count, tmp);
}
}
// If number itself is prime, it will be included
// as answer and thus minimum required answer is 1
if (max_count == 0) {
max_count = 1;
}
return max_count;
}
// Driver Code to test above functions
public static void Main(){
int N = 24;
Console.WriteLine("Minimum Number of Square Free Divisors is "
+ minimumSquareFreeDivisors(N));
N = 6;
Console.WriteLine("Minimum Number of Square Free Divisors is "
+ minimumSquareFreeDivisors(N));
}
// This code is contributed by Ryuga
}
输出:
Minimum Number of Square Free Divisors is 3
Minimum Number of Square Free Divisors is 1