Given a sequence of n positive integers we need to count consecutive sub-sequences whose sum is divisible by k.
Constraints : N is up to 10^6 and each element up to 10^9 and K is up to 100
EXAMPLE : Let N=5 and K=3 and array be 1 2 3 4 1
Here answer is 4
Explanation : there exists, 4 sub-sequences whose sum is divisible by 3, they are
3
1 2
1 2 3
2 3 4
My Attempt :
long long int count=0;
for(int i=0;i<n;i++){
long long int sum=0;
for(int j=i;j<n;j++)
{
sum=sum+arr[j];
if(sum%k==0)
{
count++;
}
}
}
But obviously its poor approach. Can their be better approach for this question? Please help.
Complete Question: https://www.hackerrank.com/contests/w6/challenges/consecutive-subsequences
// Stores count of subarrays with max <= k - 1. int count1 = totalSubarrays(arr, n, k - 1); // Stores count of subarrays with max >= k + 1. int count2 = totalSubarrays(arr, n, k);
The total number of subarrays in an array of size N is N * (N + 1) / 2. The count of subarrays with an odd product is equal to the total number of continuous odd elements present in the array. Therefore, count of subarrays with even product = (Total number of subarrays – Subarrays with the odd product).
We can easily calculate the number of sub-arrays of an array which has all 1s by using the formula n*(n+1)/2, where n is the length of the array with all 1s. Calculate the length of every sub-array which has all 1s and increment the count variable by length*(length+1)/2.
Here is a fast O(n + k) solution:
1)Lets compute prefix sums pref[i](for 0 <= i < n).
2)Now we can compute count[i] - the number of prefixes with sum i modulo k(0 <= i < k). This can be done by iterating over all the prefixes and making count[pref[i] % k]++. Initially, count[0] = 1(an empty prefix has sum 0) and 0 for i != 0.
3)The answer is sum count[i] * (count[i] - 1) / 2 for all i.
4)It is better to compute prefix sums modulo k to avoid overflow.
Why does it work? Let's take a closer a look at a subarray divisible by k. Let's say that it starts in L position and ends in R position. It is divisible by k if and only if pref[L - 1] == pref[R] (modulo k) because their differnce is zero modulo k(by definition of divisibility). So for each fixed modulo, we can pick any two prefixes with this prefix sum modulo k(and there are exactly count[i] * (count[i] - 1) / 2 ways to do it).
Here is my code:
long long get_count(const vector<int>& vec, int k) {
//Initialize count array.
vector<int> cnt_mod(k, 0);
cnt_mod[0] = 1;
int pref_sum = 0;
//Iterate over the input sequence.
for (int elem : vec) {
pref_sum += elem;
pref_sum %= k;
cnt_mod[pref_sum]++;
}
//Compute the answer.
long long res = 0;
for (int mod = 0; mod < k; mod++)
res += (long long)cnt_mod[mod] * (cnt_mod[mod] - 1) / 2;
return res;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With