HDU1892 See you~
二维树状数组,注意树状数组下标不能从0开始, 且注意数据中 x1, y1 对于x2, y2不一定是左上角和右上角
#include<algorithm> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std; int bk[1005][1005]; int n=1004; int lowbit(int x) { return x&(-x); } int query(int x,int y) { int tp, ret=0; while(x>0) { tp=y; while(tp>0) { ret+=bk[x][tp]; tp-=lowbit(tp); } x-=lowbit(x); } return ret; } void add(int va,int x,int y) { int tp; while(x<=n) { tp=y; while(tp<=n) { bk[x][tp]+=va; tp+=lowbit(tp); } x+=lowbit(x); } } int get(int x1,int y1,int x2,int y2) { int s1, s2, s3, s4; s1=query(x1-1,y1-1); s2=query(x1-1,y2); s3=query(x2,y1-1); s4=query(x2,y2); return s4-s2-s3+s1; } int main() { int T, ri, x1, y1, x2, y2, i, j, va, m; char s[3]; scanf("%d",&T); for(ri=1;ri<=T;ri++) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) bk[i][j]=0; for(i=1;i<=n;i++) for(j=1;j<=n;j++) add(1,i,j); scanf("%d",&m); printf("Case %d:\n",ri); for(i=1;i<=m;i++) { scanf("%s",s); if(s[0]=='S') { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); x1++, y1++, x2++, y2++; if(x1>x2) swap(x1,x2); if(y1>y2) swap(y1,y2); printf("%d\n",get(x1,y1,x2,y2)); } else if(s[0]=='A') { scanf("%d%d%d",&x1,&y1,&va); x1++, y1++; add(va,x1,y1); } else if(s[0]=='D') { scanf("%d%d%d",&x1,&y1,&va); x1++, y1++; int tmp=min(get(x1,y1,x1,y1),va); add(-tmp,x1,y1); } else { scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&va); x1++, y1++, x2++, y2++; int tmp=min(get(x1,y1,x1,y1),va); add(-tmp,x1,y1); add(tmp,x2,y2); } } } return 0; }