多维树状数组

匿名 (未验证) 提交于 2019-12-02 23:48:02

hdu2642

http://acm.hdu.edu.cn/showproblem.php?pid=2642

题目大意:

现在假设天空是一个二维平面(1000*1000)。坐标从(0,0)点开始。现在给出N条信息。

"B X Y",B为字符,x、y是整数,表示将坐标(x,y)的星星变亮。

"D XY",D为字符,x、y是整数,表示将坐标(x,y)的星星变暗。

"Q X1 X2 Y1 Y2",Q是字符,X1、X2、Y1、Y2是整数,表示问有多少颗星星在X1、X2、

Y1、Y2确定的矩形中。

思路:

建立一个二维的树状数组,单点更新,区间求值。其实和一维的差不多。只不过第i个元素变

为了第x行第y列的元素。更新和求值都是二维维护数组数组。再用一个二维数组Mark[][]表

示(x、y)处的星星的明暗情况。因为坐标是从(0,0)点开始的,而Lowbit(0) = 0,所以,另

所有的横纵坐标都加1,使坐标从(1,1)点开始。

#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int M=1e3+3; int a[M][M],vis[M][M]; int lowbit(int x){     return x&(-x); } void update(int x,int y,int c){     for(int i=x;i<M;i+=lowbit(i))         for(int j=y;j<M;j+=lowbit(j))             a[i][j]+=c; } int sum(int x,int y){     int ans=0;     for(int i=x;i>0;i-=lowbit(i))         for(int j=y;j>0;j-=lowbit(j))             ans+=a[i][j];     return ans; } char s[2]; int main(){     int n;     scanf("%d",&n);     for(int i=1;i<=n;i++){         scanf("%s",s);         if(s[0]=='Q'){             int x1,x2,y1,y2;             scanf("%d%d%d%d",&x1,&x2,&y1,&y2);             x1++,x2++,y1++,y2++;             if(x1<x2)                 swap(x1,x2);             if(y1<y2)                 swap(y1,y2);             printf("%d\n",sum(x1,y1)+sum(x2-1,y2-1)-sum(x1,y2-1)-sum(x2-1,y1));         }         else{             int x,y;             scanf("%d%d",&x,&y);             x++,y++;             if(s[0]=='B'){                 if(!vis[x][y]){                     vis[x][y]=1;                     update(x,y,1);                 }             }             else{                 if(vis[x][y]){                     vis[x][y]=0;                     update(x,y,-1);                 }             }         }     }     return 0; }
View Code

 

转载请标明出处:多维树状数组
文章来源: 多维树状数组
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!