您的位置:首页 > 其它

poj 1195 mobile phones 二维树状数组

2014-07-12 13:03 323 查看
这道题就是一道比较裸的二维树状数组,刚练完一维后,可以来做一做。

我觉得一维树状数组思路是很清晰的,而二维树状数组比较抽象,所以必须透彻理解一维树状数组后,才能稍微明白二维的。

在纸上先画个二维图,然后边画边想便理解,有点像二重积分,二重循环。。。

这道题题意是说:大小为S*S的区域内,每个小格中初始化时有0个手机,然后通过不同的操作,可以像每个小格中添加手机,最后查询某个矩形区域内手机的总个数。

附上代码:

#include <iostream>

using namespace std;

int a[1030][1030]; //二维树状数组

int s; //区域的边长

int lowbit(int t)

{

return t&(-t);

}

void insert(int x,int y,int d) //;两个循环维护数组区间

{

while(x<=s)

{

int y1=y;

while(y1<=s)

{

a[x][y1]+=d;

y1+=lowbit(y1);

}

x+=lowbit(x);

}

}

long long getsum(int x,int y) //求取一个区域内的手机数量

{

long long sum=0;

while(x>0)

{

int y1=y;

while(y1>0)

{

sum+=a[x][y1];

y1-=lowbit(y1);

}

x-=lowbit(x);

}

return sum;

}

int main()

{

int x1,x2,y1,y2,flag;

double d;

while(cin>>flag)

{

if(flag==3)break;

else if(flag==0)

{

cin>>s;



for(int i=1;i<=s;i++) //初始化,使得最开始每个小格内的手机数量为0

for(int j=1;j<=s;j++)

{

a[i][j]=0;

a[j][i]=0;

}

}

else if(flag==1)

{

cin>>x1>>y1>>d;

x1++;y1++; //之所以要++是因为树状数组不能从0开始计数

insert(x1,y1,d);

}

else if(flag==2)

{

cin>>x1>>y1>>x2>>y2;

x1++;y1++;x2++;y2++;

long long sum=0;

sum=getsum(x2,y2)-getsum(x1-1,y2)-getsum(x2,y1-1)+getsum(x1-1,y1-1); //画画图便于理解

printf("%lld\n",sum);

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: