📌  相关文章
📜  计算素数的GCD幂等于1的范围内的数字

📅  最后修改于: 2021-04-24 20:24:02             🧑  作者: Mango

给定由两个正整数LR表示的范围。任务是对具有素数幂的GCD等于1的范围内的数进行计数。换句话说,如果数X的素数分解形式为2 p 1 * 3 p 2 * 5 p 3 *…,p 1 ,p 2 ,p 3的GCD应该等于1

例子:

先决条件:在一定范围内拥有完美的力量
天真的方法:迭代从LR的所有数字,并对每个数字进行素数分解,然后计算素数的幂的GCD。如果GCD = 1 ,则增加一个计数变量,最后返回它作为答案。

高效方法:此处的关键思想是要注意有效数不是完美幂,因为质数因子的幂总是使它们的GCD始终大于1。换句话说,所有完美幂都不是有效数。
例如

因此,我们可以找到处于该范围内的理想功效的总数,并将其从总数中减去。

下面是上述方法的实现:

CPP
// C++ implementation of the approach
#include 
  
using namespace std;
  
#define N 1000005
#define MAX 1e18
  
// Vector to store powers greater than 3
vector powers;
  
// Set to store perfect squares
set squares;
  
// Set to store powers other than perfect squares
set s;
  
void powersPrecomputation()
{
    for (long int i = 2; i < N; i++) {
  
        // Pushing squares
        squares.insert(i * i);
  
        // if the values is already a perfect square means
        // present in the set
        if (squares.find(i) != squares.end())
            continue;
  
        long int temp = i;
  
        // Run loop until some power of current number
        // doesn't exceed MAX
        while (i * i <= MAX / temp) {
            temp *= (i * i);
  
            // Pushing only odd powers as even power of a number 
            // can always be expressed as a perfect square 
            // which is already present in set squares
            s.insert(temp);
        }
    }
  
    // Inserting those sorted
    // values of set into a vector
    for (auto x : s)
        powers.push_back(x);
}
  
long int calculateAnswer(long int L, long int R)
{
  
    // Precompute the powers
    powersPrecomputation();
  
    // Calculate perfect squares in
    // range using sqrtl function
    long int perfectSquares = floor(sqrtl(R)) - floor(sqrtl(L - 1));
  
    // Calculate upper value of R
    // in vector using binary search
    long int high = upper_bound(powers.begin(),
                                powers.end(), R)
                    - powers.begin();
  
    // Calculate lower value of L
    // in vector using binary search
    long int low = lower_bound(powers.begin(),
                               powers.end(), L)
                   - powers.begin();
  
    // Calculate perfect powers
    long perfectPowers = perfectSquares + (high - low);
  
    // Compute final answer
    long ans = (R - L + 1) - perfectPowers;
    return ans;
}
  
// Driver Code
int main()
{
    long int L = 13, R = 20;
    cout << calculateAnswer(L, R);
    return 0;
}


Java
// Java implementation of above idea
import java.util.*;
  
class GFG 
{
  
    static int N = 1000005;
    static long MAX = (long) 1e18;
  
    // Vector to store powers greater than 3
    static Vector powers = new Vector<>();
  
    // Set to store perfect squares
    static TreeSet squares = new TreeSet<>();
  
    // Set to store powers other than perfect squares
    static TreeSet s = new TreeSet<>();
  
    static void powersPrecomputation()
    {
        for (long i = 2; i < N; i++)
        {
  
            // Pushing squares
            squares.add(i * i);
  
            // if the values is already a perfect square means
            // present in the set
            if (squares.contains(i))
                continue;
  
            long temp = i;
  
            // Run loop until some power of current number
            // doesn't exceed MAX
            while (i * i <= MAX / temp)
            {
                temp *= (i * i);
  
                // Pushing only odd powers as even power of a number
                // can always be expressed as a perfect square
                // which is already present in set squares
                s.add(temp);
            }
        }
  
        // Inserting those sorted
        // values of set into a vector
        for (long x : s)
            powers.add(x);
    }
  
    static long calculateAnswer(long L, long R)
    {
  
        // Precompute the powers
        powersPrecomputation();
  
        // Calculate perfect squares in
        // range using sqrtl function
        long perfectSquares = (long) (Math.floor(Math.sqrt(R)) - 
                                Math.floor(Math.sqrt(L - 1)));
  
        // Calculate upper value of R
        // in vector using binary search
        long high = Collections.binarySearch(powers, R);
  
        // Calculate lower value of L
        // in vector using binary search
        long low = Collections.binarySearch(powers, L);
  
        // Calculate perfect powers
        long perfectPowers = perfectSquares + (high - low);
  
        // Compute final answer
        long ans = (R - L + 1) - perfectPowers;
        return ans;
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        long L = 13, R = 20;
        System.out.println(calculateAnswer(L, R));
    }
}
  
// This code is contributed by
// sanjeev2552


Python3
# Python3 implementation of the approach
from bisect import bisect as upper_bound
from bisect import bisect_left as lower_bound
from math import floor
N = 1000005
MAX = 10**18
  
# Vector to store powers greater than 3
powers = []
  
# Set to store perfect squares
squares = dict()
  
# Set to store powers other than perfect squares
s = dict()
  
def powersPrecomputation():
  
    for i in range(2, N):
  
        # Pushing squares
        squares[i * i] = 1
  
        # if the values is already a perfect square means
        # present in the set
        if (i not in squares.keys()):
            continue
  
        temp = i
  
        # Run loop until some power of current number
        # doesn't exceed MAX
        while (i * i <= (MAX // temp)):
            temp *= (i * i)
  
            # Pushing only odd powers as even power of a number
            # can always be expressed as a perfect square
            # which is already present in set squares
            s[temp]=1
  
    # Inserting those sorted
    # values of set into a vector
    for x in s:
        powers.append(x)
  
def calculateAnswer(L, R):
  
    # Precompute the powers
    powersPrecomputation()
  
    # Calculate perfect squares in
    # range using sqrtl function
    perfectSquares = floor((R)**(.5)) - floor((L - 1)**(.5))
  
    # Calculate upper value of R
    # in vector using binary search
    high = upper_bound(powers,R)
  
    # Calculate lower value of L
    # in vector using binary search
    low = lower_bound(powers,L)
  
    # Calculate perfect powers
    perfectPowers = perfectSquares + (high - low)
  
    # Compute final answer
    ans = (R - L + 1) - perfectPowers
  
    return ans
  
  
# Driver Code
  
L = 13
R = 20
print(calculateAnswer(L, R))
  
# This code is contributed by mohit kumar 29


C#
// C# implementation of above idea
using System;
using System.Collections.Generic;
  
public class GFG 
{
  
    static int N = 100005;
    static long MAX = (long) 1e18;
  
    // List to store powers greater than 3
    static List powers = new List();
  
    // Set to store perfect squares
    static HashSet squares = new HashSet();
  
    // Set to store powers other than perfect squares
    static HashSet s = new HashSet();
  
    static void powersPrecomputation()
    {
        for (long i = 2; i < N; i++)
        {
  
            // Pushing squares
            squares.Add(i * i);
  
            // if the values is already a perfect square means
            // present in the set
            if (squares.Contains(i))
                continue;
  
            long temp = i;
  
            // Run loop until some power of current number
            // doesn't exceed MAX
            while (i * i <= MAX / temp)
            {
                temp *= (i * i);
  
                // Pushing only odd powers as even power of a number
                // can always be expressed as a perfect square
                // which is already present in set squares
                s.Add(temp);
            }
        }
  
        // Inserting those sorted
        // values of set into a vector
        foreach (long x in s)
            powers.Add(x);
    }
  
    static long calculateAnswer(long L, long R)
    {
  
        // Precompute the powers
        powersPrecomputation();
  
        // Calculate perfect squares in
        // range using sqrtl function
        long perfectSquares = (long) (Math.Floor(Math.Sqrt(R)) - 
                                Math.Floor(Math.Sqrt(L - 1)));
  
        // Calculate upper value of R
        // in vector using binary search
        long high = Array.BinarySearch(powers.ToArray(), R);
  
        // Calculate lower value of L
        // in vector using binary search
        long low = Array.BinarySearch(powers.ToArray(), L);
  
        // Calculate perfect powers
        long perfectPowers = perfectSquares + (high - low);
  
        // Compute readonly answer
        long ans = (R - L + 1) - perfectPowers;
        return ans;
    }
  
    // Driver Code
    public static void Main(String[] args)
    {
        long L = 13, R = 20;
        Console.WriteLine(calculateAnswer(L, R));
    }
}
  
// This code is contributed by 29AjayKumar


输出:
7