简单的二维树状数组,求一个矩形区域内的和,因为要随时增减,而且可能减的数比原来都大,所以需要保留原来的数组。
在求矩形区域和的时候,只要用最大的矩形减去两个小的,再加上那个多减的最小的,就OK了.
- #include<iostream>
- #define M 1300
- int c[M][M],a[M][M],n;
- int lowbit(int t){
- return t&(t^(t-1));
- }
- int sum(int p,int q){
- int x=p,y,total=0;
- while(x>0){
- y=q;
- while(y>0){
- total+=c[x][y];
- y-=lowbit(y);
- }
- x-=lowbit(x);
- }
- return total;
- }
- void modify(int p,int q,int key){
- int x=p,y;
- while(x<=n){
- y=q;
- while(y<=n){
- c[x][y]+=key;
- y+=lowbit(y);
- }
- x+=lowbit(x);
- }
- }
- int main()
- {
- int i,j,k,jj,kk,m,order,ans;
- scanf("%d%d",&i,&n);
- memset(c,0,sizeof(c));
- memset(a,0,sizeof(a));
- while(scanf("%d",&order)!=EOF){
- if(order==3) break;
- else if(order==1){
- scanf("%d%d%d",&j,&k,&m);
- ++j; ++k;
- if(m<0&&m*(-1)>a[j][k]){
- m=(-1)*a[j][k];
- modify(j,k,m);
- a[j][k]=0;
- }
- else{
- modify(j,k,m);
- a[j][k]+=m;
- }
- }
- else if(order==2){
- scanf("%d%d%d%d",&j,&jj,&k,&kk);
- ++j; ++jj; ++k; ++kk;
- //printf("%d ",sum(n,n));
- ans=sum(k,kk)+sum(j-1,jj-1)-sum(k,jj-1)-sum(j-1,kk);
- printf("%d/n",ans);
- }
- }
- }