题目描述
输入
输出
样例输入
1
3 4 4
Q 1 1 1 1
Q 1 1 3 2
M 1 1 3
Q 1 1 3 4
样例输出
2
21
55
思路:
sum[i][j] 代表数组A中第i行前 j 个数字的前缀和,每一次更新只更新每行前缀和。
(做这题的时候想过前缀和,但是没做出来,还是同学说了他的思路才明白了,太蠢 orz。)
每块的总和,用每行的前缀和一行一行的加起来。
最差的时间复杂度:20*1000*1000。
代码:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1010;
long long sum[N][N];
long long a[N][N];
int main()
{
int T;
cin >> T;
int n, m, q;
char op;
int x1, y1, x2, y2;
int x, y, v;
for(int t=1; t<=T; t++) {
cin >> n >> m >> q;
memset(sum, 0, sizeof(sum));
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
sum[i][j] = (i+1+i+j)*(j)/2; // 初始化 sum[][]
a[i][j] = i+j;
}
}
for(int i=1; i<=q; i++) {
cin >> op;
if(op == 'Q') {
/* for(int j=1; j<=n; j++) {
for(int k=1; k<=m; k++) {
cout << sum[j][k] << " ";
}
cout << endl;
}*/
long long ans = 0;
cin >> x1 >> y1 >> x2 >> y2;
for(int j=x1; j<=x2; j++) {
ans += sum[j][y2]-sum[j][y1-1];
}
cout << ans << endl;
}
else {
cin >> x >> y >> v;
for(int j=y; j<=m; j++) {
sum[x][j] += (v-a[x][y]);
}
a[x][y] = v;
}
}
}
return 0;
}