洛谷P3941入阵曲题解

题目信息

题目传送门

解题思路

  • 枚举行的上与下界,时间复杂度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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒟蒻一枚

谢谢鸭~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值