Find a permutation such that number of indices for which gcd(p[i], i) > 1 is exactly K

Given two integers N and K, the task is to find a permutation of integers from the range [1, N] such that the number of indices (1-based indexing) where gcd(p[i], i) > 1 is exactly K. Print -1 if such permutation is not possible.

Examples:

Input: N = 4, K = 3
Output: 1 2 3 4
gcd(1, 1) = 1
gcd(2, 2) = 2
gcd(3, 3) = 3
gcd(4, 4) = 4
Therefore, there are exactly 3 indices where gcd(p[i], i) > 1

Input: N = 1, K = 1
Output: -1

Approach: A couple of observations can be made here:

  1. gcd(i, i + 1) = 1
  2. gcd(1, i) = 1
  3. gcd(i, i) = i

Since, gcd of 1 with any other number is always going to be one, K can atmost be N – 1. Consider the permutation where p[i] = i, The number of indices where gcd(p[i], i) > 1 will be N – 1. Notice that swapping 2 continuous elements (excluding 1) will reduce the count of such indices by exactly 2. And swapping with 1 will reduce the count by exactly 1.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the appraoch
#include <bits/stdc++.h>
using namespace std;
  
// Function to print the required permutation
void printPermutation(int n, int k)
{
  
    // Not possible
    if (k >= n || (n % 2 == 0 && k == 0)) {
        cout << -1;
        return;
    }
    int per[n + 1], i;
  
    // Initial permutation
    for (i = 1; i <= n; i++)
        per[i] = i;
  
    // Indices for which gcd(p[i], i) > 1
    // in the initial permutation
    int cnt = n - 1;
    i = 2;
    while (i < n) {
  
        // Reduce the count by 2
        if (cnt - 1 > k) {
            swap(per[i], per[i + 1]);
            cnt -= 2;
        }
  
        // Reduce the count by 1
        else if (cnt - 1 == k) {
            swap(per[1], per[i]);
            cnt--;
        }
        else
            break;
        i += 2;
    }
  
    // Print the permutation
    for (i = 1; i <= n; i++)
        cout << per[i] << " ";
}
  
// Driver code
int main()
{
    int n = 4, k = 3;
    printPermutation(n, k);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the appraoch 
class GFG
{
  
// Function to print the required permutation 
    static void printPermutation(int n, int k)
    {
  
        // Not possible 
        if (k >= n || (n % 2 == 0 && k == 0)) 
        {
            System.out.print(-1);
            return;
        }
        int per[] = new int[n + 1], i;
  
        // Initial permutation 
        for (i = 1; i <= n; i++)
        {
            per[i] = i;
        }
  
        // Indices for which gcd(p[i], i) > 1 
        // in the initial permutation 
        int cnt = n - 1;
        i = 2;
        while (i < n) 
        {
  
            // Reduce the count by 2 
            if (cnt - 1 > k)
            {
                swap(per, i, i + 1);
                cnt -= 2;
            
              
            // Reduce the count by 1 
            else if (cnt - 1 == k) 
            {
                swap(per, 1, i);
                cnt--;
            
            else
            {
                break;
            }
            i += 2;
        }
  
        // Print the permutation 
        for (i = 1; i <= n; i++)
        {
            System.out.print(per[i] + " ");
        }
    }
  
    static int[] swap(int[] arr, int i, int j)
    {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
        return arr;
    }
      
    // Driver code 
    public static void main(String[] args)
    {
        int n = 4, k = 3;
        printPermutation(n, k);
    }
}
  
/* This code contributed by PrinciRaj1992 */

chevron_right


Python3

# Python3 implementation of the approach

# Function to print the required permutation
def printPermutation(n, k):

# Not possible
if (k >= n or (n % 2 == 0 and
k == 0)):
print(-1);
return;
per = [0] * (n + 1);

# Initial permutation
for i in range(1, n + 1):
per[i] = i;

# Indices for which gcd(p[i], i) > 1
# in the initial permutation
cnt = n – 1;
i = 2;
while (i < n): # Reduce the count by 2 if (cnt - 1 > k):

t = per[i];
per[i] = per[i + 1];
per[i + 1] = t;

# swap(per[i], per[i + 1]);
cnt -= 2;

# Reduce the count by 1
elif (cnt – 1 == k):

# swap(per[1], per[i]);
t = per[1];
per[1] = per[i];
per[i] = t;
cnt -= 1;
else:
break;
i += 2;

# Print the permutation
for i in range(1, n + 1):
print(per[i], end = ” “);

# Driver code
n = 4;
k = 3;
printPermutation(n, k);

# This code is contributed by mits

C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the appraoch 
using System;
  
class GFG 
  
    // Function to print the required permutation 
    static void printPermutation(int n, int k) 
    
  
        // Not possible 
        if (k >= n || (n % 2 == 0 && k == 0)) 
        
            Console.Write(-1); 
            return
        
        int []per = new int[n + 1] ;
        int i ; 
  
        // Initial permutation 
        for (i = 1; i <= n; i++) 
        
            per[i] = i; 
        
  
        // Indices for which gcd(p[i], i) > 1 
        // in the initial permutation 
        int cnt = n - 1; 
        i = 2; 
        while (i < n) 
        
  
            // Reduce the count by 2 
            if (cnt - 1 > k) 
            
                swap(per, i, i + 1); 
                cnt -= 2; 
            
              
            // Reduce the count by 1 
            else if (cnt - 1 == k) 
            
                swap(per, 1, i); 
                cnt--; 
            
            else
            
                break
            
            i += 2; 
        
  
        // Print the permutation 
        for (i = 1; i <= n; i++) 
        
            Console.Write(per[i] + " "); 
        
    
  
    static int[] swap(int[] arr, int i, int j) 
    
        int temp = arr[i]; 
        arr[i] = arr[j]; 
        arr[j] = temp; 
        return arr; 
    
      
    // Driver code 
    public static void Main() 
    
        int n = 4, k = 3; 
        printPermutation(n, k); 
    
  
/* This code contributed by Ryuga */

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation of the approach
  
// Function to print the required permutation
function printPermutation($n, $k)
{
  
    // Not possible
    if ($k >= $n || ($n % 2 == 0 && 
                     $k == 0)) 
    {
        echo -1;
        return;
    }
    $per[$n + 1] = array();
    $i;
  
    // Initial permutation
    for ($i = 1; $i <= $n; $i++)
        $per[$i] = $i;
  
    // Indices for which gcd(p[i], i) > 1
    // in the initial permutation
    $cnt = $n - 1;
    $i = 2;
    while ($i < $n
    {
  
        // Reduce the count by 2
        if ($cnt - 1 > $k)
        {
              
            list($per[$i], 
                 $per[$i + 1]) = array($per[$i + 1],
                                       $per[$i]);
            //swap(per[i], per[i + 1]);
            $cnt -= 2;
        }
  
        // Reduce the count by 1
        else if ($cnt - 1 == $k
        {
              
            // swap(per[1], per[i]);
            list($per[1], 
                 $per[$i]) = array($per[$i],
                                   $per[1]);
            $cnt--;
        }
        else
            break;
        $i += 2;
    }
  
    // Print the permutation
    for ($i = 1; $i <= $n; $i++)
        echo $per[$i], " ";
}
  
// Driver code
$n = 4;
$k = 3;
printPermutation($n, $k);
  
// This code is contributed by ajit.
?>

chevron_right


Output:

1 2 3 4

Time Complexity: O(N)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.