矩阵(差分)

题目大意:考虑一个\(n \times n\)的矩阵A,初始所有元素均为0.执行q次如下形式的操作:给定4个整数r,c,l,s,对于每个满足\(x∈[r,r+l),y∈[c,x−r+c]\)的元素(x,y),将权值增加s.也就是给一个左上顶点为(r,c)直角边长为l的下三角区域加上s.输出最终矩阵的元素异或和.

二维前缀和

考虑这么一个三角形:(假装有图.)

我们如果差分做的话,是对每一行的开头都加s对每一行的结尾的后一个数字都减去s

所以我们对查分数组再维护一个差分数组

对这个区域的(r,c)位置加上s,对竖着的(r+l,c)位置(结尾的下一行)减去s

对这个区域的(r,c+1)位置减去s,对他右下角再往右往下一个格子(r+l,c+l+1)加上s(因为本来是要对他们这种吊车尾减去s的嘛)

然后累加然后统计就好了

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <bits/stdc++.h>
#define int long long
#define ll long long
using namespace std;

const int N = 1e3 + 66;

int n, q, res;
int cnm[N][N], fuck[N][N], a[N][N];

signed main()
{
int i, j, r, c, l, s;
n = read(), q = read();
while (q --)
{
r = read(), c = read(), l = read(), s = read();
cnm[r][c] += s;
cnm[min(r + l, n + 1)][c] -= s;
fuck[r][c + 1] -= s;
fuck[min(r + l, n + 1)][min(c + l + 1, n + 1)] += s;
}
for (i = 1; i <= n; ++ i) for (j = 1; j <= n; ++ j)
{
cnm[i][j] += cnm[i - 1][j];
fuck[i][j] += fuck[i - 1][j - 1];
}
for (i = 1; i <= n; ++ i) for (j = 1; j <= n; ++ j)
{
a[i][j] = cnm[i][j] + a[i][j - 1] + fuck[i][j];
res ^= a[i][j];
}
put(res);
return 0;
}

后记:

从没有见过此种类型题

第一次见,长见识了!