树状数组(2)

来源:互联网 发布:星际穿越知乎 编辑:程序博客网 时间:2024/05/21 06:26

1、POJ 1195 Mobile phones

 http://acm.pku.edu.cn/JudgeOnline/problem?id=1195

二维的树状数组,要参照一维画图理解。

#include <stdio.h>#include <string.h>const int MAX = 1030;int size;int c[MAX][MAX];int lowbit(int x){return x&(-x);}void update(int x, int y, int t){int i, j;for (i=x; i<=size; i+=lowbit(i)){for  (j=y; j<=size; j+=lowbit(j)){c[i][j] += t;}}}int getsum(int x, int y){int i, j, sum = 0;for (i=x; i>0; i-=lowbit(i)){for (j=y; j>0; j-=lowbit(j)){sum += c[i][j];}}return sum;}int main(){int ins, x, y, A, l, b, r, t;memset(c, 0, sizeof(c));while (scanf("%d", &ins) == 1){if (ins == 0){scanf("%d", &size);}if (ins == 1){scanf("%d%d%d", &x, &y, &A);x++;y++;update(x, y, A);}if (ins == 2){scanf("%d%d%d%d", &l, &b, &r, &t);l++;b++;r++;t++;printf("%d\n", getsum(r, t) - getsum(r, b-1) - getsum(l-1, t) + getsum(l-1, b-1));}if (ins== 3){break;}}return 0;}


2、POJ 2029 Get Many Persimmon Trees

 http://acm.pku.edu.cn/JudgeOnline/problem?id=2029

需要枚举起点,然后用二维树状数组,更新即可。

 

#include <stdio.h>#include <string.h>#define max(x,y) (x)>(y)?(x):(y)const int MAX = 505;int c[MAX][MAX];int lowbit(int x){return x&(-x);}void update(int x, int y, int v){int i, j;for (i=x; i<MAX; i+=lowbit(i)){for (j=y; j<MAX; j+=lowbit(j)){c[i][j] += v;}}}int getsum(int x, int y){int i, j, sum = 0;for (i=x; i>0; i-=lowbit(i)){for (j=y; j>0; j-=lowbit(j)){sum += c[i][j];}}return sum;}int main(){int n, w, h, x, y, s, t, i, j, ans;while (scanf("%d", &n) == 1, n){ans = 0;scanf("%d%d", &w, &h);memset(c, 0, sizeof(c));for (i=0; i<n; i++){scanf("%d%d", &x, &y);update(x, y, 1);}scanf("%d%d", &s, &t);for (i=1; i<=w-s+1; i++){for (j=1; j<=h-t+1; j++){ans = max(ans, getsum(i+s-1,j+t-1)+getsum(i-1, j-1)-getsum(i+s-1, j-1)-getsum(i-1, j+t-1));}}printf("%d\n", ans);}return ans;}

3、SPOJ 1029 Matrix Summation

 https://www.spoj.pl/problems/MATSUM/

依旧是二维

 

#include <stdio.h>#include <string.h>const int MAX = 1024 + 10;char ins[5];int n, a[MAX][MAX], c[MAX][MAX], x, y;int lowbit(int x){return x&(-x);}void update(int x, int y, int v){int i, j;for (i=x; i<=n; i+=lowbit(i)){for (j=y; j<=n; j+=lowbit(j)){c[i][j]+=v;}}}int getsum(int x, int y){int i, j, sum = 0;for (i=x; i>0; i-=lowbit(i)){for (j=y; j>0; j-=lowbit(j)){sum += c[i][j];}}return sum;}int main(){int Case, v;while(scanf("%d", &Case) == 1){while (Case--){scanf("%d", &n);memset(a, 0, sizeof(a));memset(c, 0, sizeof(c));while (scanf("%s", ins)==1&&strcmp(ins, "END")){if (strcmp(ins, "SET") == 0){scanf("%d%d%d", &x, &y, &v);x++;y++;update(x, y, v-a[x][y]);a[x][y] = v;}if (strcmp(ins, "SUM") == 0){int x1, y1, x2, y2;scanf("%d%d%d%d", &x1, &y1, &x2, &y2);x1++;y1++;x2++;y2++;printf("%d\n", getsum(x2,y2) + getsum(x1-1, y1-1) - getsum(x2, y1-1)-getsum(x1-1, y2));}}}}return 0;}