Here is a quick solution to O (n + k):
1) Allows to calculate prefix sums pref [i] (for 0 <= i <n).
2) Now we can calculate count [i] - the number of prefixes with the sum i modulo k (0 <= i <k). This can be done by iterating through all the prefixes and doing count [pref [i]% k] ++. Initially, count [0] = 1 (an empty prefix has the sum 0) and 0 for i! = 0.
3) The answer is the sum of count [i] * (count [i] - 1) / 2 for all i.
4) It is better to calculate the prefix sums modulo k to avoid overflow.
Why does it work? Let's go closer to the submatrix divisible by k. Let's say that it starts in the L-position and ends in the R-position. It is divisible by k if and only if pref [L - 1] == pref [R] (modulo k), since their difference is equal to zero modulo k (by the definition of divisibility). Thus, for each fixed modulo we can choose any two prefixes with this prefix sum modulo k (and there is exactly an account [i] * (count [i] - 1) / 2 ways to do this).
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; }
source share