poj1195解题报告-树状数组
题目大意:在一个2维的x,y坐标轴内,被划分成了正方形,该正方形是由s*s的矩阵构成(行和列都是从0~s-1)。可以输入0,1,2,3这些指令
指令:0:0 s---初始化s*s的矩阵,也就是全部置0.
指令1:1 X Y A---向正方形(x,y)中加入手机数为A(注意A可能为负数),但是题目中保证正方形(x,y)中手机的个数不会为负数。
指令2:2 L B R T---查询区域(x,y)区域内的手机数目(L=<x<=R,B=<y<=T).
指令3:3---表示程序结束。
题目分析:由于s题目中给的比较大,很明显的树状数组题。题意中又给的需要x,y坐标,建立个2维的树状数组就可以搞定了,这题需要特别注意坐标(i,j)不能为0,否则就会陷入死循环,代码中解释。
我AC的代码:
#include<iostream>
using namespace std;
const int N=1030;
int c[N][N];
int row,col;
//-------------2维数组的一般模板
int lowbit(const int x)
{
return x&(-x);
}
int sum(int i,int j)
{
int tempj,sum=0;
while(i>0)
{
tempj=j;
while(tempj>0)
{
sum+=c[i][tempj];
tempj-=lowbit(tempj); //---注意lowbit(0)=0,如果i,j的值等于0,程序就会陷入死循环。
}
i-=lowbit(i); //---同上
}
return sum;
}
void update(int i,int j,int num)
{
int tempj;
while(i<=row)
{
tempj=j;
while(tempj<=col)
{
c[i][tempj]+=num;
tempj+=lowbit(tempj); //---同上
}
i+=lowbit(i); //---同上
}
}
//-----------------
int main()
{
int z,s;
scanf("%d",&z); //z表示输入进来的指令
while(z<3)
{
if(z==0)
{
scanf("%d",&s);
row=s;
col=s;
memset(c,0,sizeof(c));
}
if(z==1)
{
int x,y,a;
scanf("%d%d%d",&x,&y,&a);
update(x+1,y+1,a); //---注意为了使(i,j)的值不会为0,就将(X,Y)在储存时x,y的值都加上1.
}
if(z==2)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
printf("%d\n",sum(x2+1,y2+1)-sum(x1,y2+1)-sum(x2+1,y1)+sum(x1,y1)); //----这里需要自己理解下,区间(x,y),x1=<x<=x2;y1=<y<=y2的范围内的手机数目为什么是这么写的【sum(x,y)表示的是从(0,0)到(x,y)区域内的手目】
}
scanf("%d",&z);
}
return 0;
}