Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 17496 | Accepted: 8089 |
Description
Input
Output
Sample Input
0 4 1 1 2 3 2 0 0 2 2 1 1 1 2 1 1 2 -1 2 1 1 2 3 3
Sample Output
3 4
Source
题意:
一个由数字构成的大矩阵,开始是全0,能进行两种操作
1) 对矩阵里的某个数加上一个整数(可正可负)
2) 查询某个子矩阵里所有数字的和
要求对每次查询,输出结果
题解:模板题,使用二维线段树或者二维树状数组数组
以下给出2种做法:
1:二维树状数组
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<string> #include<bitset> #include<utility> #include<functional> #include<iomanip> #include<sstream> #include<ctime> using namespace std; #define N int(3e3) #define inf int(0x3f3f3f3f) #define mod int(1e9+7) typedef long long LL; #ifdef CDZSC #define debug(...) fprintf(stderr, __VA_ARGS__) #else #define debug(...) #endif int n,c[N][N]; int lowbit(int x) { return x&(-x); } int query_sum(int x, int y) { int res = 0; for (int i = x; i > 0; i -= lowbit(i)) { for (int j = y; j > 0; j -= lowbit(j)) { res += c[i][j]; } } return res; } void add(int x, int y, int val) { for (int i = x; i <= n; i += lowbit(i)) { for (int j = y; j <= n; j += lowbit(j)) { c[i][j] += val; } } } int main() { #ifdef CDZSC freopen("i.txt", "r", stdin); //freopen("o.txt","w",stdout); int _time_jc = clock(); #endif int s, x, y, a, L, b, R, t; while (~scanf("%d%d", &s, &n)) { memset(c, 0, sizeof(c)); while (~scanf("%d", &s)) { if (s == 3)break; if (s == 1) { scanf("%d%d%d", &x, &y, &a); add(x + 1, y + 1, a); } else { scanf("%d%d%d%d", &L, &b, &R, &t); L++; b++; R++; t++; printf("%d\n", query_sum(R, t) - query_sum(R, b - 1) - query_sum(L - 1, t) + query_sum(L - 1, b - 1)); } } } #ifdef CDZSC debug("time: %d\n", int(clock() - _time_jc)); #endif return 0; }
2:二维线段树
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<string> #include<bitset> #include<utility> #include<functional> #include<iomanip> #include<sstream> #include<ctime> using namespace std; #define N int(1e3+50) #define inf int(0x3f3f3f3f) #define mod int(1e9+7) typedef long long LL; #ifdef CDZSC #define debug(...) fprintf(stderr, __VA_ARGS__) #else #define debug(...) #endif int S,tree[N<<2][N<<2]; void update_x(int rooty, int rootx, int L, int R, int x, int a) //tree[rooty][rootx]对应的矩阵x方向上范围是[L,R] { tree[rooty][rootx] += a; if( L == R ) return; int mid = (L + R )/2; if( x <= mid ) update_x(rooty,( rootx << 1) + 1, L ,mid, x, a); else update_x(rooty,( rootx << 1) + 2, mid + 1,R, x, a); } void update_y(int rooty, int L, int R, int y, int x, int a) //tree[rooty][rootx]对应的矩阵y方向上范围是[L,R] { update_x( rooty,0, 1, S, x,a); if( L == R) return; int mid = (L + R )/2; if( y <= mid ) update_y( ( rooty << 1) + 1, L, mid,y, x, a); else update_y( ( rooty << 1) + 2, mid+1, R, y, x, a); } int query_x(int rooty, int rootx, int L, int R, int x1, int x2) { if (L == x1 && R == x2) return tree[rooty][rootx]; int mid = (L + R) / 2; if (x2 <= mid) return query_x(rooty, (rootx << 1) + 1, L, mid, x1, x2); else if (x1 > mid) return query_x(rooty, (rootx << 1) + 2, mid + 1, R, x1, x2); else return query_x(rooty, (rootx << 1) + 1, L, mid, x1, mid) + query_x(rooty, (rootx << 1) + 2, mid + 1, R, mid + 1, x2); } int query_y(int rooty, int L, int R, int y1, int y2, int x1, int x2) { if (L == y1 && R == y2) return query_x(rooty, 0, 1, S, x1, x2); int mid = (L + R) / 2; if (y2 <= mid) return query_y((rooty << 1) + 1, L, mid, y1, y2, x1, x2); if (y1 > mid) return query_y((rooty << 1) + 2, mid + 1, R, y1, y2, x1, x2); else return query_y((rooty << 1) + 1, L, mid, y1, mid, x1, x2) + query_y((rooty << 1) + 2, mid + 1, R, mid + 1, y2, x1, x2); } int main() { #ifdef CDZSC freopen("i.txt", "r", stdin); //freopen("o.txt","w",stdout); int _time_jc = clock(); #endif int n, s, x, y, a, L, b, R, t; while (~scanf("%d%d", &s, &S)) { while (~scanf("%d", &s)) { if (s == 3)break; if (s == 1) { scanf("%d%d%d", &x, &y, &a); update_y(0, 1, S, y + 1, x + 1, a); } else { scanf("%d%d%d%d", &L, &b, &R, &t); L++; b++; R++; t++; printf("%d\n", query_y(0, 1, S,b, t, L, R)); } } } #ifdef CDZSC debug("time: %d\n", int(clock() - _time_jc)); #endif return 0; }