📜  最小平方除数

📅  最后修改于: 2021-04-24 18:03:00             🧑  作者: Mango

给定整数N。找到最小平方自由因数。换句话说,N的因式分解应仅包含那些无平方的除数。平方自由数是不能被任何理想平方整除的数字(当然,在这种情况下,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

下图说明了上述算法

下面是上述方法的实现。在这里,我们将进行预处理以找到主要因素(使用筛分法),以便我们可以同时回答许多查询。

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