hduu 1892 see you~~~二维树状数组

WA了几次,都是一些小问题,不够细心,总是这样

这几天一直就在搞线段树和树状数组,也不知道怎么说好,对于树状数组更新区间问题

依依然云里雾里的说,我想是我还是没有理解好树状数组那两个函数的本质

在网上看到一个博文说其实它们本质是一样的,可以交换使用,不过自己还没有

测试过

#include<stdio.h> #include<string.h> #define EXCHANGE(a,b) (a) ^= (b);(b) ^= (a);(a) ^= (b) #define N 1005 int tree[N][N]; int arr[N][N];//这个数组还是很重要的说,避免了一些查询 int lowbit(int x) { return x&(-x); } void buid_tree() { int x = 1,y = 1; while(x < N){//定成x <= N直接RE了两次 y = 1; while(y < N){ tree[x][y] = lowbit(x)*lowbit(y);//这里的初始化 arr[x][y] = 1; y++; } x++; } } int tree_search(int x,int y) { int sum = 0; int flagy; while(x >= 1){ flagy = y; while(flagy >= 1){ sum += tree[x][flagy]; flagy -= lowbit(flagy); } x -= lowbit(x); } return sum; } void tree_change(int x,int y,int data) { int flagy; while(x < N){ flagy = y; while(flagy < N){ tree[x][flagy] += data; flagy += lowbit(flagy); } x += lowbit(x); } } int main() { int tcase; int q; int i; int x1,y1,x2,y2; int n1; int walk = 0; int sum; char ch; scanf("%d",&tcase); while(tcase--){ scanf("%d",&q); buid_tree(); printf("Case %d:/n",++walk); for(i = 0;i < q;i++){ getchar(); ch = getchar(); if(ch == 'S'){ scanf("%d %d %d %d",&x1,&y1,&x2,&y2); x1++; y1++; x2++; y2++; if(x1 > x2) {EXCHANGE(x1,x2);}//宏定义一定要加花括号的说, if(y1 > y2) {EXCHANGE(y1,y2);}//一开始压根不知道要交换坐标值,结果直接WA了 sum = tree_search(x2,y2)-tree_search(x1-1,y2)-tree_search(x2,y1-1)+tree_search(x1-1,y1-1);//好像叫什么容斥原理,只要画个图就很清楚了 printf("%d/n",sum); } if(ch == 'A'){ scanf("%d %d %d",&x1,&y1,&n1); x1++; y1++; arr[x1][y1] += n1; tree_change(x1,y1,n1); } if(ch == 'D'){ scanf("%d %d %d",&x1,&y1,&n1); x1++; y1++; if(arr[x1][y1] < n1) n1 = arr[x1][y1]; tree_change(x1,y1,-n1); arr[x1][y1] -= n1; } if(ch == 'M'){ scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&n1); x1++; y1++; x2++; y2++; if(arr[x1][y1] < n1) n1 = arr[x1][y1]; tree_change(x1,y1,-n1); arr[x1][y1] -= n1;//这里也忘了更新数组arr[][] tree_change(x2,y2,n1); arr[x2][y2] += n1; } } } return 0; }#include<stdio.h> #include<string.h> #define EXCHANGE(a,b) (a) ^= (b);(b) ^= (a);(a) ^= (b) #define N 1005 int tree[N][N]; int arr[N][N];//这个数组还是很重要的说,避免了一些查询 int lowbit(int x) { return x&(-x); } void buid_tree() { int x = 1,y = 1; while(x < N){//定成x <= N直接RE了两次 y = 1; while(y < N){ tree[x][y] = lowbit(x)*lowbit(y);//这里的初始化 arr[x][y] = 1; y++; } x++; } } int tree_search(int x,int y) { int sum = 0; int flagy; while(x >= 1){ flagy = y; while(flagy >= 1){ sum += tree[x][flagy]; flagy -= lowbit(flagy); } x -= lowbit(x); } return sum; } void tree_change(int x,int y,int data) { int flagy; while(x < N){ flagy = y; while(flagy < N){ tree[x][flagy] += data; flagy += lowbit(flagy); } x += lowbit(x); } } int main() { int tcase; int q; int i; int x1,y1,x2,y2; int n1; int walk = 0; int sum; char ch; scanf("%d",&tcase); while(tcase--){ scanf("%d",&q); buid_tree(); printf("Case %d:/n",++walk); for(i = 0;i < q;i++){ getchar(); ch = getchar(); if(ch == 'S'){ scanf("%d %d %d %d",&x1,&y1,&x2,&y2); x1++; y1++; x2++; y2++; if(x1 > x2) {EXCHANGE(x1,x2);}//宏定义一定要加花括号的说, if(y1 > y2) {EXCHANGE(y1,y2);}//一开始压根不知道要交换坐标值,结果直接WA了 sum = tree_search(x2,y2)-tree_search(x1-1,y2)-tree_search(x2,y1-1)+tree_search(x1-1,y1-1);//好像叫什么容斥原理,只要画个图就很清楚了 printf("%d/n",sum); } if(ch == 'A'){ scanf("%d %d %d",&x1,&y1,&n1); x1++; y1++; arr[x1][y1] += n1; tree_change(x1,y1,n1); } if(ch == 'D'){ scanf("%d %d %d",&x1,&y1,&n1); x1++; y1++; if(arr[x1][y1] < n1) n1 = arr[x1][y1]; tree_change(x1,y1,-n1); arr[x1][y1] -= n1; } if(ch == 'M'){ scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&n1); x1++; y1++; x2++; y2++; if(arr[x1][y1] < n1) n1 = arr[x1][y1]; tree_change(x1,y1,-n1); arr[x1][y1] -= n1;//这里也忘了更新数组arr[][] tree_change(x2,y2,n1); arr[x2][y2] += n1; } } } return 0; }

你可能感兴趣的:(hduu 1892 see you~~~二维树状数组)