HDU1892

来源:互联网 发布:知乎rss订阅地址 编辑:程序博客网 时间:2024/06/08 11:39

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1892

二维树状数组模板题,要注意书的数量不够时该位置的书的数量变为0。

在查询区段值的时候的代码(最开始写的时候y直接用的,找了好久才找出错来):

int sum(int x,int y){int tot=0;for(;x;x-=lb(x)){for(int j=y;j;j-=lb(j))tot+=tree[i][j];//int j=y而不直接用y }return tot;}

代码:

#include <cstdio>#include <cstring>#include <iostream>#include <cstdlib>#include <algorithm>#include <map>using namespace std;const int maxn=1010;int a[maxn][maxn];int tree[maxn][maxn];int n;int lb(int x){return x&-x;}int read(int x,int y){int tot=0;for(int i=x;i;i-=lb(i)){for(int j=y;j;j-=lb(j))tot+=tree[i][j];}return tot;}void add(int num,int x,int y){for(int i=x;i<maxn;i+=lb(i)){for(int j=y;j<maxn;j+=lb(j)){tree[i][j]+=num;}}}int main(){int _;scanf("%d",&_);for(int k=1;k<=_;k++){memset(tree,0,sizeof(tree));for(int i=1;i<maxn;i++){for(int j=1;j<maxn;j++){a[i][j]=1;add(1,i,j);}}scanf("%d",&n);printf("Case %d:\n",k);for(int i=1;i<=n;i++){char c[4];scanf("%s",c);if(c[0]=='A'){int x,y,t;scanf("%d%d%d",&x,&y,&t);x++,y++;add(t,x,y);a[x][y]+=t;}if(c[0]=='D'){int x,y,t;scanf("%d%d%d",&x,&y,&t);x++;y++;if(a[x][y]>=t){add(-t,x,y);a[x][y]-=t;}else{add(-a[x][y],x,y);a[x][y]=0;}}if(c[0]=='S'){int x1,y1,x2,y2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);x1++;y1++;x2++;y2++;int xmax,ymax,xmin,ymin;xmin=min(x1,x2);xmax=max(x1,x2);ymin=min(y1,y2);ymax=max(y1,y2);int ans=read(xmax,ymax)+read(xmin-1,ymin-1)-read(xmin-1,ymax)-read(xmax,ymin-1);printf("%d\n",ans);}if(c[0]=='M'){int x1,y1,x2,y2,t;scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&t);x1++;y1++;x2++;y2++;if(a[x1][y1]>=t){add(-t,x1,y1);add(t,x2,y2);a[x1][y1]-=t;a[x2][y2]+=t;}else{add(-a[x1][y1],x1,y1);add(a[x1][y1],x2,y2);a[x2][y2]+=a[x1][y1];a[x1][y1]=0;}}}}return 0;}


原创粉丝点击