您的位置:首页 > 其它

poj1195解题报告-树状数组

2020-02-03 04:30 204 查看

题目大意:在一个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

;
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;
}

 

转载于:https://www.cnblogs.com/yanhanxiaoGO/archive/2012/05/07/2489358.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
asd212313 发布了0 篇原创文章 · 获赞 0 · 访问量 95 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: