Skip to content
Related Articles

Related Articles

Improve Article
Count number of pairs (i, j) up to N that can be made equal on multiplying with a pair from the range [1, N / 2]
  • Difficulty Level : Hard
  • Last Updated : 01 Jun, 2021

Given a positive even integer N, the task is to find the number of pairs (i, j) from the range [1, N] such that the product of i and L1 is the same as the product of j and L2 where i < j and L1 and L2 any number from the range [1, N/2].

Examples:

Input: N = 4
Output: 2
Explanation:
The possible pairs satisfying the given criteria are:

  1. (1, 2): As 1 < 2, and 1*2 = 2*1 where L1 = 2 and L2 = 1.
  2. (2, 4): As 2 < 4 and 2*2 = 4*1 where L1 = 2 and L2 = 1.

Therefore, the total count is 2.

Input: N = 6
Output: 7



Naive Approach: The given problem can be solved based on the following observations:

Let i * L1 = j * L2 = lcm(i, j) — (1)
⇒ L1 = lcm(i, j)/ i
= j/gcd(i, j)

Similarly, L2 = i/gcd(i, j)

Now, for the condition to be satisfied, L1 and L2 must be in the range [1, N/2].

Therefore, the idea is to generate all possible pairs (i, j) over the range [1,  N] and if there exist any pair (i, j) such that the value of i/gcd(i, j) and j/gcd(i, j) is less than N/2, then increment the count of pairs by 1. After checking for all the pairs, print the value of the count as the result.

Time Complexity: O(N2*log N)
Auxiliary Space: O(1)

Efficient Approach: The above approach can also be optimized by using Euler’s Totient function. There exist the following 2 cases for any pair (i, j):

  • Case 1: If the pair (i, j) lies in the range [1, N/2], then all the possible pairs formed will satisfy the given condition. Therefore, the total count of pairs is given by (z*(z – 1))/2, where z = N/2.
  • Case 2: If all possible pairs (i, j) lies in the range [N/2 + 1, N] having gcd(i, j) is greater than 1 satisfy the given conditions.

Follow the steps below to count the total number of this type of pairs:

  • Compute Φ for all numbers smaller than or equal to N by using Euler’s Totient function for all numbers smaller than or equal to N.
  • For a number j, the total number of possible pairs (i, j) can be calculated as (j – Φ(j) – 1).
  • For each number in the range [N/2 + 1, N], count the total number pairs using the above formula.
  • After completing the above steps, print the sum of values obtained in the above two steps as the result.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
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




<script>
 
// Javascript program implementation
// of the approach
 
// Function to compute totient of all
// numbers smaller than or equal to N
function computeTotient(N, phi)
{
      
    // Iterate over the range [2, N]
    for(let 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(let 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
function countPairs(N)
{
      
    // Stores the counts of first and
    // second type of pairs respectively
    let cnt_type1 = 0, cnt_type2 = 0;
  
    // Count of first type of pairs
    let half_N = N / 2;
    cnt_type1 = (half_N * (half_N - 1)) / 2;
  
    // Stores the  phi or totient values
    let phi = Array.from({length: N+1}, (_, i) => 0);
  
    for(let i = 1; i <= N; i++)
    {
        phi[i] = i;
    }
  
    // Calculate the Phi values
    computeTotient(N, phi);
  
    // Iterate over the range
    // [N/2 + 1, N]
    for(let i = (N / 2) + 1;
            i <= N; i++)
  
        // Update the value of
        // cnt_type2
        cnt_type2 += (i - phi[i] - 1);
  
    // Print the total count
    document.write(cnt_type1 + cnt_type2);
}
 
// Driver Code
     
    let N = 6;
      
    countPairs(N);
  
 // This code is contributed by souravghosh0416.
</script>
Output: 
7

 

Time Complexity: O(N*log(log(N)))
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes




My Personal Notes arrow_drop_up
Recommended Articles
Page :