题目信息
解题思路
- 枚举行的上与下界,时间复杂度O(n2)
- 从左向右遍历,若当前前缀和为sumi,则如果i前面有j符合ai≡aj(mod k),则i和j之间数的和必定满足mod k == 0的条件,时间复杂度O(n)。
分析
时间复杂度:O(n3)
空间复杂度:O(n2)
不太懂前缀和的童鞋出门右转。
代码实现
#include <bits/stdc++.h>
using namespace std;
const int N = 405, K = 1e6 + 5;
int a[N][N];
long long s[N][N];
int cnt[K];
int n, m, k;
long long res;
void solve(int y1, int y2) {
long long sum = 0;
for (int i = 1; i <= n; ++i) {
sum = (sum + s[i][y2] - s[i][y1 - 1]) % k;
res += cnt[sum];
++cnt[sum];
}
sum = 0;
for (int i = 1; i <= n; ++i) {
sum = (sum + s[i][y2] - s[i][y1 - 1]) % k;
--cnt[sum];
}
}
int main() {
cin >> n >> m >> k;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
cin >> a[i][j];
s[i][j] = s[i][j - 1] + a[i][j];
}
}
cnt[0] = 1;
for (int y1 = 1; y1 <= m; ++y1) {
for (int y2 = y1; y2 <= m; ++y2) {
solve(y1, y2);
}
}
cout << res << '\n';
return 0;
}