题目描述
输入
输出
样例输入
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; }