注意树状数组的初始化,c[i][j] = lowbit(i)*lowbit(j)与add(i,j,1)等价!
因为树状数组的lowbit作用是提取出x的最低位1.
#define N 1100
int c[N][N];
int g[N][N];
int lowbit(int x){
return x&(-x);
}
void add(int i,int j,int x){
int tmp;
while(i<N){
tmp = j;
while(tmp<N){
c[i][tmp]+=x;
tmp+=lowbit(tmp);
}
i+=lowbit(i);
}
}
int sum(int i,int j){
int ans=0;
int tmp;
while(i>0){
tmp = j;
while(tmp>0){
ans+=c[i][tmp];
tmp-=lowbit(tmp);
}
i-=lowbit(i);
}
return ans;
}
int main(){
int t;
scanf("%d",&t);
int ca=1;
while(t--){
int n;
scanf("%d",&n);
int i,j;
for(i=1;i<N;i++){
for(j=1;j<N;j++){
g[i][j] = 1;
c[i][j] = lowbit(i)*lowbit(j);//add(i,j,1);
}
}
printf("Case %d:\n",ca++);
while(n--){ //0<=x1,y1,x2,y2<=1000
char str[3];
scanf("%s",str);
if(str[0] == 'S'){
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int x,xx,y,yy;
x = min(x1,x2),xx = max(x1,x2);
x++,xx++;
y = min(y1,y2),yy = max(y1,y2);
y++,yy++;
int ans = sum(xx,yy)-sum(xx,y-1)-sum(x-1,yy)+sum(x-1,y-1);
printf("%d\n",ans);
} else if(str[0] == 'A'){
int x,y,a;
scanf("%d%d%d",&x,&y,&a);
x++,y++;
add(x,y,a);
g[x][y]+=a;
} else if(str[0] == 'D'){
int x,y,a;
scanf("%d%d%d",&x,&y,&a);
x++,y++;
if(a>g[x][y])a = g[x][y];
add(x,y,-a);
g[x][y]-=a;
} else if(str[0] == 'M'){
int x1 ,y1, x2, y2, n1;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&n1);
x1++,y1++;
x2++,y2++;
if(g[x1][y1]<n1){
n1 = g[x1][y1];
}
add(x1,y1,-n1);
add(x2,y2,n1);
g[x1][y1] -= n1;
g[x2][y2] += n1;
}
}
}
return 0;
}

本文深入讲解了树状数组的基本概念及其实现原理,包括lowbit函数的作用、如何使用add函数更新数组元素、如何通过sum函数求区间和等内容,并提供了一个完整的示例程序,帮助读者更好地理解和掌握树状数组的应用。
261

被折叠的 条评论
为什么被折叠?



