📜  Q查询中LCM不等于其乘积的N个对的计数

📅  最后修改于: 2021-04-22 03:29:56             🧑  作者: Mango

给定数字N ,任务是找到[1,N]范围内的对(a,b)数,以使它们的LCM不等于其乘积,即LCM(a,b)!=(a * b)(b> a) 。可能有多个查询要回答。

例子:

方法:想法是使用Euler的Totient函数。

  1. 用1到N找出可以形成的对的总数。形成的对数等于(N *(N – 1))/ 2
  2. 对于每个i≤N的整数,使用Euler的Totient函数查找与i互质的所有此类对,并将其存储在数组中。
    例子:
    arr[10] = 10 * (1-1/2) * (1-1/5)
            = 4
    

  3. 现在建立前缀总和表,该表存储1至N之间的所有i的所有phi(i)的总和。使用此表,我们可以在O(1)时间内回答每个查询。
  4. 最后,任何i≤N的答案都由形成的对总数与pref [i]之差给出。

下面是给定方法的实现:

C++
// C++ program to find the count of pairs
// from 1 to N such that their LCM
// is not equal to their product
#include 
using namespace std;
  
#define N 100005
  
// To store Euler's Totient Function
int phi[N];
  
// To store prefix sum table
int pref[N];
  
// Compute Totients of all numbers
// smaller than or equal to N
void precompute()
{
    // Make phi[1]=0 since 1 cannot form any pair
    phi[1] = 0;
  
    // Initialise all remaining phi[] with i
    for (int i = 2; i < N; i++)
        phi[i] = i;
  
    // Compute remaining phi
    for (int p = 2; p < N; p++) {
  
        // If phi[p] is not computed already,
        // then number p is prime
        if (phi[p] == p) {
  
            // phi of prime number is p-1
            phi[p] = p - 1;
  
            // Update phi of all multiples of p
            for (int i = 2 * p; i < N; i += p) {
  
                // Add the contribution of p
                // to its multiple i by multiplying
                // it with (1 - 1/p)
                phi[i] = (phi[i] / p) * (p - 1);
            }
        }
    }
}
  
// Function to store prefix sum table
void prefix()
{
    // Prefix Sum of all Euler's Totient Values
    for (int i = 1; i < N; i++)
        pref[i] = pref[i - 1] + phi[i];
}
  
void find_pairs(int n)
{
  
    // Total number of pairs that can be formed
    int total = (n * (n - 1)) / 2;
  
    int ans = total - pref[n];
  
    cout << "Number of pairs from 1 to "
         << n << " are " << ans << endl;
}
  
// Driver Code
int main()
{
  
    // Function call to compute all phi
    precompute();
  
    // Function call to store all prefix sum
    prefix();
  
    int q[] = { 5, 7 };
    int n = sizeof(q) / sizeof(q[0]);
  
    for (int i = 0; i < n; i++) {
        find_pairs(q[i]);
    }
  
    return 0;
}


Java
// Java program to find the count of pairs
// from 1 to N such that their LCM
// is not equal to their product
  
class GFG{
  
static final int N = 100005;
  
// To store Euler's Totient Function
static int []phi = new int[N];
  
// To store prefix sum table
static int []pref = new int[N];
  
// Compute Totients of all numbers
// smaller than or equal to N
static void precompute()
{
    // Make phi[1] = 0 since 1 cannot form any pair
    phi[1] = 0;
  
    // Initialise all remaining phi[] with i
    for (int i = 2; i < N; i++)
        phi[i] = i;
  
    // Compute remaining phi
    for (int p = 2; p < N; p++) {
  
        // If phi[p] is not computed already,
        // then number p is prime
        if (phi[p] == p) {
  
            // phi of prime number is p-1
            phi[p] = p - 1;
  
            // Update phi of all multiples of p
            for (int i = 2 * p; i < N; i += p) {
  
                // Add the contribution of p
                // to its multiple i by multiplying
                // it with (1 - 1/p)
                phi[i] = (phi[i] / p) * (p - 1);
            }
        }
    }
}
  
// Function to store prefix sum table
static void prefix()
{
    // Prefix Sum of all Euler's Totient Values
    for (int i = 1; i < N; i++)
        pref[i] = pref[i - 1] + phi[i];
}
  
static void find_pairs(int n)
{
  
    // Total number of pairs that can be formed
    int total = (n * (n - 1)) / 2;
  
    int ans = total - pref[n];
  
    System.out.print("Number of pairs from 1 to "
        + n + " are " + ans +"\n");
}
  
// Driver Code
public static void main(String[] args)
{
  
    // Function call to compute all phi
    precompute();
  
    // Function call to store all prefix sum
    prefix();
  
    int q[] = { 5, 7 };
    int n = q.length;
  
    for (int i = 0; i < n; i++) {
        find_pairs(q[i]);
    }
  
}
}
  
// This code contributed by Rajput-Ji


Python3
# Python 3 program to find the count of pairs
# from 1 to N such that their LCM
# is not equal to their product
  
N = 100005
  
# To store Euler's Totient Function
phi = [0 for i in range(N)]
  
# To store prefix sum table
pref = [0 for i in range(N)]
  
# Compute Totients of all numbers
# smaller than or equal to N
def precompute():
  
    # Make phi[1]=0 since 1 cannot form any pair
    phi[1] = 0
  
    # Initialise all remaining phi[] with i
    for i in range(2, N, 1):
        phi[i] = i
  
    # Compute remaining phi
    for p in range(2,N):
        # If phi[p] is not computed already,
        # then number p is prime
        if (phi[p] == p):
            # phi of prime number is p-1
            phi[p] = p - 1
  
            # Update phi of all multiples of p
            for i in range(2*p, N, p):
  
                # Add the contribution of p
                # to its multiple i by multiplying
                # it with (1 - 1/p)
                phi[i] = (phi[i] // p) * (p - 1)
  
# Function to store prefix sum table
def prefix():
  
    # Prefix Sum of all Euler's Totient Values
    for i in range(1, N, 1):
        pref[i] = pref[i - 1] + phi[i]
  
def find_pairs(n):
    # Total number of pairs that can be formed
    total = (n * (n - 1)) // 2
  
    ans = total - pref[n]
  
    print("Number of pairs from 1 to",n,"are",ans)
  
# Driver Code
if __name__ == '__main__':
    # Function call to compute all phi
    precompute()
  
    # Function call to store all prefix sum
    prefix()
  
    q =  [5, 7]
    n = len(q)
  
    for i in range(n):
        find_pairs(q[i])
          
# This code is contributed by Surendra_Gangwar


C#
// C# program to find the count of pairs
// from 1 to N such that their LCM
// is not equal to their product
using System;
  
class GFG{
  
static readonly int N = 100005;
  
// To store Euler's Totient Function
static int []phi = new int[N];
  
// To store prefix sum table
static int []pref = new int[N];
  
// Compute Totients of all numbers
// smaller than or equal to N
static void precompute()
{
  
    // Make phi[1] = 0 since 1
    // cannot form any pair
    phi[1] = 0;
  
    // Initialise all remaining 
    // phi[] with i
    for(int i = 2; i < N; i++)
       phi[i] = i;
  
    // Compute remaining phi
    for(int p = 2; p < N; p++)
    {
         
       // If phi[p] is not computed already,
       // then number p is prime
       if (phi[p] == p)
       {
             
           // phi of prime number is p-1
           phi[p] = p - 1;
             
           // Update phi of all multiples of p
           for(int i = 2 * p; i < N; i += p)
           {
                
              // Add the contribution of p
              // to its multiple i by multiplying
              // it with (1 - 1/p)
              phi[i] = (phi[i] / p) * (p - 1);
           }
       }
    }
}
  
// Function to store prefix sum table
static void prefix()
{
      
    // Prefix Sum of all 
    // Euler's Totient Values
    for(int i = 1; i < N; i++)
       pref[i] = pref[i - 1] + phi[i];
}
  
static void find_pairs(int n)
{
  
    // Total number of pairs 
    // that can be formed
    int total = (n * (n - 1)) / 2;
    int ans = total - pref[n];
  
    Console.Write("Number of pairs from 1 to " + 
                      n + " are " + ans + "\n");
}
  
// Driver Code
public static void Main(String[] args)
{
  
    // Function call to compute all phi
    precompute();
  
    // Function call to store
    // all prefix sum
    prefix();
  
    int []q = {5, 7};
    int n = q.Length;
  
    for(int i = 0; i < n; i++)
    {
       find_pairs(q[i]);
    }
}
}
  
// This code is contributed by Rajput-Ji


输出:
Number of pairs from 1 to 5 are 1
Number of pairs from 1 to 7 are 4