HDU 1892 二维树状数组
2013-09-02 22:29
302 查看
题意,在1000*1000的二维矩阵里,每个点初始有一本书,然后有4种操作
S x1 y1 x2 y2 求 两点构成的矩形内的书总数
A x1 y1 tot 某点+tot 本书
D x1 y1 tot 某点-tot 本书,如果不足tot则变成0
M x1 y1 x2 y2 tot 从起点挪tot本到终点,如果起点不足tot则全挪
由于是点更新 ,查询区间,所以用正常的树状数组即可。
注意
_1 坐标是从0开始的,读入之后要+1
_2 每个点的状态要单独保存,因为存在不足tot这种情况
_3 初始每个点值都是1,但是不要1000*1000 的add(i,j,1),用这样一个神奇的方法
_5 正常的树状数组get(x,y)得到的是 x y (包含该行该列)左下方的和,add (x,y,v)更新的x y (包含该行该列)右上方的信息
而另一种 区间更新 查询点的 get(x,y)得到就是改点的信息, add(x,y,v)更新的是(包含该行该列) 右上方的信息
S x1 y1 x2 y2 求 两点构成的矩形内的书总数
A x1 y1 tot 某点+tot 本书
D x1 y1 tot 某点-tot 本书,如果不足tot则变成0
M x1 y1 x2 y2 tot 从起点挪tot本到终点,如果起点不足tot则全挪
由于是点更新 ,查询区间,所以用正常的树状数组即可。
注意
_1 坐标是从0开始的,读入之后要+1
_2 每个点的状态要单独保存,因为存在不足tot这种情况
_3 初始每个点值都是1,但是不要1000*1000 的add(i,j,1),用这样一个神奇的方法
for(int i=1;i<=1001;i++){ for(int j=1;j<=1001;j++){ c[i][j] = Lowbit( i ) * Lowbit( j ); }_4 查询的时候,给出的两个点有4种情况,只需求出 左下(min x ,min y),右上(max x,max y)
_5 正常的树状数组get(x,y)得到的是 x y (包含该行该列)左下方的和,add (x,y,v)更新的x y (包含该行该列)右上方的信息
而另一种 区间更新 查询点的 get(x,y)得到就是改点的信息, add(x,y,v)更新的是(包含该行该列) 右上方的信息
#include<stdio.h> #include<string.h> #include<string> using namespace std; int n=1001; int cas=1; int c[1000+10][1000+10]; int mp[1005][1005]; int Lowbit(int t){ return t&(-t); } void add(int x, int y, int val) { int i=y; while(x<=n){ y=i; while(y<=n){ c[x][y]+=val; y+=Lowbit(y); } x+=Lowbit(x); } } int get(int x, int y){ int i=y, sum=0; while(x>0){ y=i; while(y>0){ sum+=c[x][y]; y-=Lowbit(y); } x-=Lowbit(x); } return sum; } int main(){ int t,m,x1,y1,x2,y2,tot; char act[105]; scanf("%d",&t); while(t--){ scanf("%d",&m); for(int i=1;i<=1001;i++){ for(int j=1;j<=1001;j++){ c[i][j] = Lowbit( i ) * Lowbit( j ); mp[i][j]=1; } } printf("Case %d:\n",cas++); while(m--){ scanf("%s",&act); if(act[0]=='S'){ scanf("%d %d %d %d",&x1,&y1,&x2,&y2); x1++,y1++,y2++,x2++; int xx=min(x1,x2),xxx=x1+x2-xx; int yy=min(y1,y2),yyy=y1+y2-yy; int ans=0; ans+=get(xx-1,yy-1); ans+=get(xxx,yyy); ans-=get(xx-1,yyy); ans-=get(xxx,yy-1); printf("%d\n",ans); } if(act[0]=='A'){ scanf("%d %d %d",&x1,&y1,&tot); x1++,y1++,mp[x1][y1]+=tot; add(x1,y1,tot); } if(act[0]=='D'){ scanf("%d %d %d",&x1,&y1,&tot); x1++,y1++; if(mp[x1][y1]<tot)tot=mp[x1][y1]; mp[x1][y1]-=tot; add(x1,y1,-tot); } if(act[0]=='M'){ scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&tot); x1++,y1++,x2++,y2++; if(mp[x1][y1]<tot)tot=mp[x1][y1]; mp[x1][y1]-=tot,mp[x2][y2]+=tot; add(x1,y1,-tot),add(x2,y2,tot); } } } return 0; }
相关文章推荐
- hdu 1892 树状数组二维 水
- HDU 1892 (二维树状数组)
- HDU 1892 See you~(二维树状数组)
- hdu1892 See you~ 二维树状数组
- HDU 1892 See you~ (二维树状数组)
- hdu 1892 二维树状数组
- HDU 1892 See you~(经典二维树状数组)
- hdu 1892(二维树状数组模板)
- HDU 1892 See you~ (二维树状数组)
- hdu 1892 See you~(二维树状数组)
- hdu1892(二维树状数组)
- hdu 1892 see you ~(二维树状数组)
- hdu 1892 See you~(二维树状数组)
- HDU 1892 See you~(二维树状数组)
- 【树状数组+二维】杭电 hdu 1892 See you~
- hdu 1892 See you~(二维树状数组)
- HDU 1892 See you~ 二维树状数组
- hdu 1892 See you~(二维树状数组)
- HDU 1892 二维树状数组
- hdu-1892-See you~ 二维树状数组