📌  相关文章
📜  计算与范围 [1, N / 2] 中的一对相乘时可以相等的对 (i, j) 的数量,最多为 N

📅  最后修改于: 2022-05-13 01:56:09.607000             🧑  作者: Mango

计算与范围 [1, N / 2] 中的一对相乘时可以相等的对 (i, j) 的数量,最多为 N

给定一个正偶整数N ,任务是从范围[1, N]中找到对(i, j)的数量,使得iL 1的乘积与jL 2的乘积相同,其中i < jL 1L 2范围[1, N/2]中的任何数字。

例子:

朴素方法:可以根据以下观察解决给定的问题:

因此,我们的想法是在[1, N]范围内生成所有可能的对(i, j) ,如果存在任何对(i, j) ,使得i/gcd(i, j)j/ gcd(i, j)小于N/2 ,然后将对数增加1 。检查所有对后,打印计数值作为结果。

时间复杂度: O(N 2 *log N)
辅助空间: O(1)

高效方法:上述方法也可以通过使用欧拉的Totient函数进行优化。任何对(i, j)都存在以下两种情况:

  • 情况 1:如果对(i, j)位于[1, N/2]范围内,则形成的所有可能对将满足给定条件。因此,对的总数由(z*(z – 1))/2给出,其中z = N/2
  • 情况 2:如果所有可能的对(i, j)位于[N/2 + 1, N]范围内,且gcd(i, j)大于1 ,则满足给定条件。

请按照以下步骤计算此类对的总数:

  • 对所有小于或等于N的数字使用欧拉的 Totient函数计算所有小于或等于 N 的数字的Φ
  • 对于数字j ,可能对(i, j)的总数可以计算为(j – Φ(j) – 1)
  • 对于[N/2 + 1, N]范围内的每个数字,使用上述公式计算总数对。
  • 完成上述步骤后,将上述两步得到的值的总和打印出来作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to compute totient of all
// numbers smaller than or equal to N
void computeTotient(int N, int phi[])
{
    // Iterate over the range [2, N]
    for (int p = 2; p <= N; p++) {
 
        // If phi[p] is not computed
        // already, then p is prime
        if (phi[p] == p) {
 
            // Phi of a prime number
            // p is (p - 1)
            phi[p] = p - 1;
 
            // Update phi values of
            // all multiples of p
            for (int i = 2 * p; i <= N;
                 i += p) {
 
                // Add contribution of p
                // to its multiple i by
                // multiplying with (1 - 1/p)
                phi[i] = (phi[i] / p) * (p - 1);
            }
        }
    }
}
 
// Function to count the pairs (i, j)
// from the range [1, N], satisfying
// the given condition
void countPairs(int N)
{
    // Stores the counts of first and
    // second type of pairs respectively
    int cnt_type1 = 0, cnt_type2 = 0;
 
    // Count of first type of pairs
    int half_N = N / 2;
    cnt_type1 = (half_N * (half_N - 1)) / 2;
 
    // Stores the  phi or totient values
    int phi[N + 1];
 
    for (int i = 1; i <= N; i++) {
        phi[i] = i;
    }
 
    // Calculate the Phi values
    computeTotient(N, phi);
 
    // Iterate over the range
    // [N/2 + 1, N]
    for (int i = (N / 2) + 1;
         i <= N; i++)
 
        // Update the value of
        // cnt_type2
        cnt_type2 += (i - phi[i] - 1);
 
    // Print the total count
    cout << cnt_type1 + cnt_type2;
}
 
// Driver Code
int main()
{
    int N = 6;
    countPairs(N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to compute totient of all
// numbers smaller than or equal to N
static void computeTotient(int N, int phi[])
{
     
    // Iterate over the range [2, N]
    for(int p = 2; p <= N; p++)
    {
         
        // If phi[p] is not computed
        // already, then p is prime
        if (phi[p] == p)
        {
             
            // Phi of a prime number
            // p is (p - 1)
            phi[p] = p - 1;
 
            // Update phi values of
            // all multiples of p
            for(int i = 2 * p; i <= N; i += p)
            {
                 
                // Add contribution of p
                // to its multiple i by
                // multiplying with (1 - 1/p)
                phi[i] = (phi[i] / p) * (p - 1);
            }
        }
    }
}
 
// Function to count the pairs (i, j)
// from the range [1, N], satisfying
// the given condition
static void countPairs(int N)
{
     
    // Stores the counts of first and
    // second type of pairs respectively
    int cnt_type1 = 0, cnt_type2 = 0;
 
    // Count of first type of pairs
    int half_N = N / 2;
    cnt_type1 = (half_N * (half_N - 1)) / 2;
 
    // Stores the  phi or totient values
    int []phi = new int[N + 1];
 
    for(int i = 1; i <= N; i++)
    {
        phi[i] = i;
    }
 
    // Calculate the Phi values
    computeTotient(N, phi);
 
    // Iterate over the range
    // [N/2 + 1, N]
    for(int i = (N / 2) + 1;
            i <= N; i++)
 
        // Update the value of
        // cnt_type2
        cnt_type2 += (i - phi[i] - 1);
 
    // Print the total count
    System.out.print(cnt_type1 + cnt_type2);
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 6;
     
    countPairs(N);
}
}
 
// This code is contributed by Amit Katiyar


Python3
# Python3 program for the above approach
 
# Function to compute totient of all
# numbers smaller than or equal to N
def computeTotient(N, phi):
 
    # Iterate over the range [2, N]
    for p in range(2, N + 1):
 
        # If phi[p] is not computed
        # already then p is prime
        if phi[p] == p:
 
            # Phi of a prime number
            # p is (p - 1)
            phi[p] = p - 1
 
            # Update phi values of
            # all multiples of p
            for i in range(2 * p, N + 1, p):
 
                # Add contribution of p
                # to its multiple i by
                # multiplying with (1 - 1/p)
                phi[i] = (phi[i] // p) * (p - 1)
 
# Function to count the pairs (i, j)
# from the range [1, N], satisfying
# the given condition
def countPairs(N):
 
    # Stores the counts of first and
    # second type of pairs respectively
    cnt_type1 = 0
    cnt_type2 = 0
 
    # Count of first type of pairs
    half_N = N // 2
    cnt_type1 = (half_N * (half_N - 1)) // 2
 
    # Count of second type of pairs
 
    # Stores the  phi or totient values
    phi = [0 for i in range(N + 1)]
 
    for i in range(1, N + 1):
        phi[i] = i
 
    # Calculate the Phi values
    computeTotient(N, phi)
 
    # Iterate over the range
    # [N/2 + 1, N]
    for i in range((N // 2) + 1, N + 1):
 
        # Update the value of
        # cnt_type2
        cnt_type2 += (i - phi[i] - 1)
 
    # Print the total count
    print(cnt_type1 + cnt_type2)
 
# Driver Code
if __name__ == '__main__':
 
    N = 6
    countPairs(N)
 
    # This code is contributed by kundudinesh007.


C#
// C# program for the above approach
 
using System;
class GFG {
    // Function to compute totient of all
    // numbers smaller than or equal to N
    static void computeTotient(int N, int[] phi)
    {
        // Iterate over the range [2, N]
        for (int p = 2; p <= N; p++) {
 
            // If phi[p] is not computed
            // already, then p is prime
            if (phi[p] == p) {
 
                // Phi of a prime number
                // p is (p - 1)
                phi[p] = p - 1;
 
                // Update phi values of
                // all multiples of p
                for (int i = 2 * p; i <= N; i += p) {
 
                    // Add contribution of p
                    // to its multiple i by
                    // multiplying with (1 - 1/p)
                    phi[i] = (phi[i] / p) * (p - 1);
                }
            }
        }
    }
 
    // Function to count the pairs (i, j)
    // from the range [1, N], satisfying
    // the given condition
    static void countPairs(int N)
    {
        // Stores the counts of first and
        // second type of pairs respectively
        int cnt_type1 = 0, cnt_type2 = 0;
 
        // Count of first type of pairs
        int half_N = N / 2;
        cnt_type1 = (half_N * (half_N - 1)) / 2;
 
        // Stores the  phi or totient values
        int[] phi = new int[N + 1];
 
        for (int i = 1; i <= N; i++) {
            phi[i] = i;
        }
 
        // Calculate the Phi values
        computeTotient(N, phi);
 
        // Iterate over the range
        // [N/2 + 1, N]
        for (int i = (N / 2) + 1; i <= N; i++)
 
            // Update the value of
            // cnt_type2
            cnt_type2 += (i - phi[i] - 1);
 
        // Print the total count
        Console.Write(cnt_type1 + cnt_type2);
    }
 
    // Driver Code
    public static void Main()
    {
        int N = 6;
        countPairs(N);
    }
}
 
// This code is contributed by ukasp.


Javascript


输出:
7

时间复杂度: O(N*log(log(N)))
辅助空间: O(N)