Open In App

Identical Subarrays through Modulo Operations

Last Updated : 20 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N. For each divisor of N, divide the array into N/K subarrays, each of length K. Your task is to determine how many distinct values of K exist such that there is a positive integer M (where M >= 2) that, if we replace each arr[i] with arr[i] MOD K, all the subarrays become identical.

Examples:

Input: N = 4, arr[] = {1, 2, 1, 4}
Output: 2
Explanation: We have two possible values of K which satisfies the conditions:

  • For K = 2, we can have M = 2 and after replacing every element in arr[] with arr[i] % 2, the subarrays will become {1, 0}, {1, 0}.
  • For K = 4, we can have M = 2 (any number >= 2) and after replacing every element in arr[] with arr[i] % 2, the subarrays will become {1, 0, 1, 0}.

Input: N = 3, arr[] = {1, 2, 3}
Output: 1
Explanation: We have one possible value of K which satisfies the conditions:

  • For K = 3, we can have M = 2 (any number >= 2) and after replacing every element in arr[] with arr[i] % 2, the subarrays will become {1, 0, 1}.

Approach: To solve the problem, follow the below idea:

For some X and Y, let’s try to find all M such that X modulo M is congruent to Y modulo M. We can rearrange the equation into (X- Y) is congruent to 0 modulo M. Thus, if M is a factor of the absolute difference between X and Y, then X and Y will be equal modulo m.

Let’s solve for some K. A valid partition exists if there exists some M greater than 1 such that the following is true:

a1 is congruent to a1 + K modulo M

a2 is congruent to a2 + K modulo M

an-K is congruent to an modulo M

The first condition a1 is congruent to a1 + K modulo M is satisfied if M is a factor of the absolute difference between a1 and a1+K. The second condition a2 is congruent to a2 + K modulo Mis satisfied if M is a factor of the absolute difference between a2 and a2+K. And so on…

Thus, all conditions are satisfied if M is a factor of the greatest common divisor of the absolute differences between consecutive elements in the array.

So a valid M exists for some K if the greatest common divisor is greater than 1.

Step-by-step algorithm:

  • Iterate through all possible divisors ‘K’ of the array size ‘N’. For each ‘K’:
  • Partition the array into N/K disjoint subarrays of length K.
  • For each subarray, calculate the absolute differences between consecutive elements.
  • For each subarray of length ‘K’, calculate the greatest common divisor (gcd) of the absolute differences between consecutive elements.
  • If the gcd for any subarray is greater than 1, increment a counter for this ‘K’.
  • Repeat steps 1 to 3 for all divisors ‘K’.
  • The answer is the sum of the counters for all valid ‘K’.

Below is the implementation of the approach:

Java
import java.util.Arrays;

class GCDSubarrays {
    static int MOD = 1000000007;

    static void solve(int[] arr, int N)
    {
        // Variable 'ans' to store the final answer
        int ans = 0;
        // Loop to iterate through all possible divisors of
        // 'N'
        for (int K = 1; K <= N; K++) {
            // Check if 'K' is a divisor of 'N'
            if (N % K == 0) {
                // Declaration of variable 'g' to store the
                // greatest common divisor
                int g = 0;
                // Loop to calculate gcd of absolute
                // differences between consecutive elements
                // in subarrays of length 'K'
                for (int i = 0; i + K < N; i++) {
                    // Calculate gcd using abs function and
                    // store it in 'g'
                    g = gcd(g,
                            Math.abs(arr[i] - arr[i + K]));
                }
                // If gcd is not equal to 1, increment the
                // answer
                ans += (g != 1) ? 1 : 0;
            }
        }
        System.out.println(ans);
    }

    public static void main(String[] args)
    {
        int N = 4;
        int[] arr = { 1, 2, 1, 4 };
        solve(arr, N);
    }

    static int gcd(int a, int b)
    {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
}

// This code is contributed by rambabuguphka
C#
using System;

class GCDSubarrays
{
    // Method to solve the problem
    static void Solve(int[] arr, int N)
    {
        // Variable to store the final answer
        int ans = 0;
        
        // Loop through all possible divisors of 'N'
        for (int K = 1; K <= N; K++)
        {
            // Check if 'K' is a divisor of 'N'
            if (N % K == 0)
            {
                // Variable to store the greatest common divisor
                int g = 0;
                
                // Loop to calculate the greatest common divisor
                // of absolute differences between consecutive elements
                // in subarrays of length 'K'
                for (int i = 0; i + K < N; i++)
                {
                    // Calculate gcd using the GCD function and
                    // store it in 'g'
                    g = GCD(g, Math.Abs(arr[i] - arr[i + K]));
                }
                
                // If gcd is not equal to 1, increment the answer
                ans += (g != 1) ? 1 : 0;
            }
        }
        
        // Print the final answer
        Console.WriteLine(ans);
    }

    // Main method
    public static void Main(string[] args)
    {
        int N = 4;
        int[] arr = { 1, 2, 1, 4 };
        Solve(arr, N);
    }

    // Method to calculate the greatest common divisor
    static int GCD(int a, int b)
    {
        // Using Euclidean algorithm to find the GCD
        while (b != 0)
        {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
}
JavaScript
function solve (arr, N)
{
  const MOD = 1000000007;

  // Variable 'ans' to store the final answer
  let ans = 0;

  // Loop to iterate through all possible divisors of
  // 'N'
  for (let K = 1; K <= N; K++)
    {
      // Check if 'K' is a divisor of 'N'
      if (N % K === 0)
        {
          // Declaration of variable 'g' to store the
          // greatest common divisor
          let g = 0;

          // Loop to calculate gcd of absolute
          // differences between consecutive elements
          // in subarrays of length 'K'
          for (let i = 0; i + K < N; i++)
            {
              // Calculate gcd using abs function and
              // store it in 'g'
              g = gcd (g, Math.abs (arr[i] - arr[i + K]));
              
            }
          // If gcd is not equal to 1, increment the
          // answer
          ans += (g !== 1) ? 1 : 0;

        }
    }

  console.log (ans);

}

function gcd (a, b)
{
  while (b !== 0)
    {
      const temp = b;
      b = a % b;
      a = temp;
    }
  return a;
}

// Example usage:
const N = 4;
const arr =[1, 2, 1, 4];
solve (arr, N);


// This code is contributed by rohit singh
C++14
#include <bits/stdc++.h>
using namespace std;
 
#define MOD 1000000007
 
void solve(vector<int>& arr, int N)
{
    // Variable 'ans' to store the final answer
    int ans = 0;
    // Loop to iterate through all possible divisors of 'N'
    for (int K = 1; K <= N; K++) {
        // Check if 'K' is a divisor of 'N'
        if (N % K == 0) {
            // Declaration of variable 'g' to store the
            // greatest common divisor
            int g = 0;
            // Loop to calculate gcd of absolute differences
            // between consecutive elements in subarrays of
            // length 'K'
            for (int i = 0; i + K < N; i++) {
                // Calculate gcd using abs function and
                // store it in 'g'
                g = __gcd(g, abs(arr[i] - arr[i + K]));
            }
            // If gcd is not equal to 1, increment the
            // answer
            ans += (g != 1);
        }
    }
    cout << ans << "\n";
}
 
signed main()
{
    int N = 4;
    vector<int> arr = { 1, 2, 1, 4 };
    solve(arr, N);
}
Python3
def gcd(a, b):
    # Calculate the greatest common divisor (GCD) using Euclid's algorithm
    while b != 0:
        a, b = b, a % b
    return a

def solve(arr, N):
    # Variable to store the final answer
    ans = 0
    # Loop to iterate through all possible divisors of 'N'
    for K in range(1, N + 1):
        # Check if 'K' is a divisor of 'N'
        if N % K == 0:
            # Declaration of variable 'g' to store the greatest common divisor
            g = 0
            # Loop to calculate gcd of absolute differences between consecutive elements
            # in subarrays of length 'K'
            for i in range(N - K):
                # Calculate gcd using abs function and store it in 'g'
                g = gcd(g, abs(arr[i] - arr[i + K]))
            # If gcd is not equal to 1, increment the answer
            ans += 1 if g != 1 else 0
    print(ans)

# Sample input
N = 4
arr = [1, 2, 1, 4]
solve(arr, N)

Output
2

Time Complexity: O(N2*log(N)), where N is the size of input array arr[].
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads