初音未来 • 21小时前
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; // 定义长整型别名,便于处理大数据量
const int N = 2e5 + 5; // 行列最大数量,满足题目约束条件
ll a[N], b[N]; // 存储每行、每列的涂色次数(a数组记录行,b数组记录列)
int c[N], d[N]; // 统计行、列涂色次数对k取模后的余数分布情况
int main() {
// 文件输入输出重定向(根据题目要求,提交前需取消注释)
// freopen("draw.in", "r", stdin);
// freopen("draw.out", "w", stdout);
int n, m, q, k;
cin >> n >> m >> q >> k;
// 处理q次操作:记录每行每列的涂色次数
for (int i = 1; i <= q; i++) {
int op, x;
cin >> op >> x;
if (op == 1) a[x]++; // 对第x行操作次数+1
else b[x]++; // 对第x列操作次数+1
}
// 统计行涂色次数的余数分布
for (int i = 1; i <= n; i++)
c[a[i] % k]++; // 行i的涂色次数模k的余数对应c数组位置+1
// 统计列涂色次数的余数分布
for (int j = 1; j <= m; j++)
d[b[j] % k]++; // 列j的涂色次数模k的余数对应d数组位置+1
/* 关键数学优化:计算会被擦除的格子数量 */
ll total = (ll)n * m; // 所有可能的格子总数
ll same = 0; // 存储余数和为k的倍数的组合数(会被擦除的格子)
// 遍历所有可能的行余数i,计算对应的列余数j=(k-i)%k
for (int i = 0; i < k; ++i) {
int j = (k - i) % k; // 使得i + j ≡0 mod k
same += (ll)c[i] * d[j]; // 累加满足条件的组合数
}
// 最终结果 = 总格子数 - 会被擦除的格子数
ll ans = total - same;
cout << ans;
return 0;
}
评论:
请先登录,才能进行评论