Identical Subarrays through Modulo Operations
Last Updated :
20 Mar, 2024
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)
Time Complexity: O(N2*log(N)), where N is the size of input array arr[].
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...