前缀和&二维前缀和

前缀和&二维前缀和

一维前缀和:没什么好讲的。

二维前缀和:

设 $f_{i,j}$ 表示左上角为 $(0,0)$,右下角为 $(i,j)$ 的矩阵中所有数的和,则根据容斥原理,$f_{i,j}=a_{i,j}+f_{i-1,j}+f_{i,j-1}-f_{i-1,j-1}$。如图所示:

查询的时候同理,设查询 $(x_1,y_1)$ 到 $(x_2,y_2)$ 间所有数的和,则答案为 $f_{x_2,y_2}-f_{x_1-1,y_2}-f_{x_2,y_1-1}+f_{x_1-1,y_1-1}$。

代码:

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
#include<bits/stdc++.h>
using namespace std;
unsigned int n,m,q,A,B,C;
unsigned long long a[2005][2005],ans;
inline unsigned int rng61() {
A ^= A << 16;
A ^= A >> 5;
A ^= A << 1;
unsigned int t = A;
A = B;
B = C;
C ^= t ^ A;
return C;
}
int main(){
cin>>n>>m>>q>>A>>B>>C;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = rng61();
a[i][j]+=(a[i][j-1]+a[i-1][j]-a[i-1][j-1]);
}
}
for (int i = 1; i <= q; i++) {
int x1 = rng61() % n + 1, x2 = rng61() % n + 1;
int y1 = rng61() % m + 1, y2 = rng61() % m + 1;
if (x1 > x2) swap(x1, x2);
if (y1 > y2) swap(y1, y2);
ans^=a[x2][y2]-a[x1-1][y2]-a[x2][y1-1]+a[x1-1][y1-1];
}
cout<<ans;
return 0;
}

前缀和&二维前缀和
https://orangeoi.qzz.io/2026/07/31/前缀和-二维前缀和/
作者
zzy
发布于
2026年7月31日
许可协议