📜  找出对数,使它们的gcd等于1

📅  最后修改于: 2021-05-05 02:58:03             🧑  作者: Mango

给定大小为N的数组a 。任务是找到对数,使gcd(a [i],a [j])其中1≤i
例子:

方法 :
答案是μ(X)* C(D(X),3)总整数X的总和。其中, μ(X)是Mobius函数, C(N,K)是从N中选择K个事物, D(X)是给定序列中可以被X整除的整数的数量。
解决方案的正确性源于以下事实:我们可以做一个包含-排除原理的解决方案,并证明它实际上等于我们的答案。这意味着,如果D是由偶数质数的乘积形成的,那么我们将在答案中将被某个中间乘积(在IEP中) D整除的对数,否则将减去该对数。
因此,我们得到:

  • 1表示加法运算,因为这是莫比乌斯(Möbius)函数,用于除以偶数除数的无平方数。
  • -1表示减法,即Mobius函数用于素数除以奇数的无平方数。
  • 0为无平方数。根据定义,它们不会出现在我们的IEP解决方案中。

下面是上述方法的实现:

C++
// CPP program to find the number of pairs
// such that gcd equals to 1
#include 
using namespace std;
 
#define N 100050
 
int lpf[N], mobius[N];
 
// Function to calculate least
// prime factor of each number
void least_prime_factor()
{
    for (int i = 2; i < N; i++)
 
        // If it is a prime number
        if (!lpf[i])
 
            for (int j = i; j < N; j += i)
 
                // For all multiples which are not
                // visited yet.
                if (!lpf[j])
                    lpf[j] = i;
}
 
// Function to find the value of Mobius function
// for all the numbers from 1 to n
void Mobius()
{
    for (int i = 1; i < N; i++) {
 
        // If number is one
        if (i == 1)
            mobius[i] = 1;
        else {
 
            // If number has a squared prime factor
            if (lpf[i / lpf[i]] == lpf[i])
                mobius[i] = 0;
 
            // Multiply -1 with the previous number
            else
                mobius[i] = -1 * mobius[i / lpf[i]];
        }
    }
}
 
// Function to find the number of pairs
// such that gcd equals to 1
int gcd_pairs(int a[], int n)
{
    // To store maximum number
    int maxi = 0;
 
    // To store frequency of each number
    int fre[N] = { 0 };
 
    // Find frequency and maximum number
    for (int i = 0; i < n; i++) {
        fre[a[i]]++;
        maxi = max(a[i], maxi);
    }
 
    least_prime_factor();
    Mobius();
 
    // To store number of pairs with gcd equals to 1
    int ans = 0;
 
    // Traverse through the all possible elements
    for (int i = 1; i <= maxi; i++) {
        if (!mobius[i])
            continue;
 
        int temp = 0;
        for (int j = i; j <= maxi; j += i)
            temp += fre[j];
 
        ans += temp * (temp - 1) / 2 * mobius[i];
    }
 
    // Return the number of pairs
    return ans;
}
 
// Driver code
int main()
{
    int a[] = { 1, 2, 3, 4, 5, 6 };
 
    int n = sizeof(a) / sizeof(a[0]);
 
    // Function call
    cout << gcd_pairs(a, n);
 
    return 0;
}


Java
// Java program to find the number of pairs
// such that gcd equals to 1
class GFG
{
 
static int N = 100050;
 
static int []lpf = new int[N];
static int []mobius = new int[N];
 
// Function to calculate least
// prime factor of each number
static void least_prime_factor()
{
    for (int i = 2; i < N; i++)
 
        // If it is a prime number
        if (lpf[i] == 0)
 
            for (int j = i; j < N; j += i)
 
                // For all multiples which are not
                // visited yet.
                if (lpf[j] == 0)
                    lpf[j] = i;
}
 
// Function to find the value of Mobius function
// for all the numbers from 1 to n
static void Mobius()
{
    for (int i = 1; i < N; i++)
    {
 
        // If number is one
        if (i == 1)
            mobius[i] = 1;
        else
        {
 
            // If number has a squared prime factor
            if (lpf[i / lpf[i]] == lpf[i])
                mobius[i] = 0;
 
            // Multiply -1 with the previous number
            else
                mobius[i] = -1 * mobius[i / lpf[i]];
        }
    }
}
 
// Function to find the number of pairs
// such that gcd equals to 1
static int gcd_pairs(int a[], int n)
{
    // To store maximum number
    int maxi = 0;
 
    // To store frequency of each number
    int []fre = new int[N];
 
    // Find frequency and maximum number
    for (int i = 0; i < n; i++)
    {
        fre[a[i]]++;
        maxi = Math.max(a[i], maxi);
    }
 
    least_prime_factor();
    Mobius();
 
    // To store number of pairs with gcd equals to 1
    int ans = 0;
 
    // Traverse through the all possible elements
    for (int i = 1; i <= maxi; i++)
    {
        if (mobius[i] == 0)
            continue;
 
        int temp = 0;
        for (int j = i; j <= maxi; j += i)
            temp += fre[j];
 
        ans += temp * (temp - 1) / 2 * mobius[i];
    }
 
    // Return the number of pairs
    return ans;
}
 
// Driver code
public static void main (String[] args)
{
    int a[] = { 1, 2, 3, 4, 5, 6 };
 
    int n = a.length;
 
    // Function call
    System.out.print(gcd_pairs(a, n));
}
}
 
// This code is contributed by PrinciRaj1992


Python3
# Python3 program to find the number of pairs
# such that gcd equals to 1
N = 100050
 
lpf = [0 for i in range(N)]
mobius = [0 for i in range(N)]
 
# Function to calculate least
# prime factor of each number
def least_prime_factor():
 
    for i in range(2, N):
 
        # If it is a prime number
        if (lpf[i] == 0):
 
            for j in range(i, N, i):
 
                # For all multiples which are not
                # visited yet.
                if (lpf[j] == 0):
                    lpf[j] = i
 
# Function to find the value of Mobius function
# for all the numbers from 1 to n
def Mobius():
 
    for i in range(1, N):
 
        # If number is one
        if (i == 1):
            mobius[i] = 1
        else:
 
            # If number has a squared prime factor
            if (lpf[ (i // lpf[i]) ] == lpf[i]):
                mobius[i] = 0
 
            # Multiply -1 with the previous number
            else:
                mobius[i] = -1 * mobius[i // lpf[i]]
 
# Function to find the number of pairs
# such that gcd equals to 1
def gcd_pairs(a, n):
 
    # To store maximum number
    maxi = 0
 
    # To store frequency of each number
    fre = [0 for i in range(N)]
 
    # Find frequency and maximum number
    for i in range(n):
        fre[a[i]] += 1
        maxi = max(a[i], maxi)
 
    least_prime_factor()
    Mobius()
 
    # To store number of pairs with gcd equals to 1
    ans = 0
 
    # Traverse through the all possible elements
    for i in range(1, maxi + 1):
        if (mobius[i] == 0):
            continue
 
        temp = 0
        for j in range(i, maxi + 1, i):
            temp += fre[j]
 
        ans += temp * (temp - 1) // 2 * mobius[i]
 
    # Return the number of pairs
    return ans
 
# Driver code
a = [1, 2, 3, 4, 5, 6]
 
n = len(a)
 
# Function call
print(gcd_pairs(a, n))
 
# This code is contributed by Mohit Kumar


C#
// C# program to find the number of pairs
// such that gcd equals to 1
using System;
 
class GFG
{
static int N = 100050;
 
static int []lpf = new int[N];
static int []mobius = new int[N];
 
// Function to calculate least
// prime factor of each number
static void least_prime_factor()
{
    for (int i = 2; i < N; i++)
 
        // If it is a prime number
        if (lpf[i] == 0)
 
            for (int j = i; j < N; j += i)
 
                // For all multiples which are not
                // visited yet.
                if (lpf[j] == 0)
                    lpf[j] = i;
}
 
// Function to find the value of Mobius function
// for all the numbers from 1 to n
static void Mobius()
{
    for (int i = 1; i < N; i++)
    {
 
        // If number is one
        if (i == 1)
            mobius[i] = 1;
        else
        {
 
            // If number has a squared prime factor
            if (lpf[i / lpf[i]] == lpf[i])
                mobius[i] = 0;
 
            // Multiply -1 with the previous number
            else
                mobius[i] = -1 * mobius[i / lpf[i]];
        }
    }
}
 
// Function to find the number of pairs
// such that gcd equals to 1
static int gcd_pairs(int []a, int n)
{
    // To store maximum number
    int maxi = 0;
 
    // To store frequency of each number
    int []fre = new int[N];
 
    // Find frequency and maximum number
    for (int i = 0; i < n; i++)
    {
        fre[a[i]]++;
        maxi = Math.Max(a[i], maxi);
    }
 
    least_prime_factor();
    Mobius();
 
    // To store number of pairs with gcd equals to 1
    int ans = 0;
 
    // Traverse through the all possible elements
    for (int i = 1; i <= maxi; i++)
    {
        if (mobius[i] == 0)
            continue;
 
        int temp = 0;
        for (int j = i; j <= maxi; j += i)
            temp += fre[j];
 
        ans += temp * (temp - 1) / 2 * mobius[i];
    }
 
    // Return the number of pairs
    return ans;
}
 
// Driver code
public static void Main (String[] args)
{
    int []a = { 1, 2, 3, 4, 5, 6 };
 
    int n = a.Length;
 
    // Function call
    Console.Write(gcd_pairs(a, n));
}
}
     
// This code is contributed by Rajput-Ji


Javascript


输出:
11