POJ 1195 Mobile phones【二维树状数组】
<题目链接>
题目大意:
一个由数字构成的大矩阵,开始是全0,能进行两种操作
1) 对矩阵里的某个数加上一个整数(可正可负)
2) 查询某个子矩阵里所有数字的和
要求对每次查询,输出结果
解题分析:
二维树状数组模板题,需要注意的是,由于题目给的x,y坐标可以为0,所以我们应该将这些点的坐标全部+1,然后就是查询指定子矩阵中所有元素之和,很直观的就能得到式子 ans=sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1)。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int M = 2e3; 7 int row,col,tr[M][M]; 8 int lowbit(int x){return x&(-x);} 9 void add(int i,int j,int val){ 10 int tmpj; 11 while(i<=row){ 12 tmpj=j; 13 while(tmpj<=col){ 14 tr[i][tmpj]+=val; 15 tmpj+=lowbit(tmpj); 16 } 17 i+=lowbit(i); 18 } 19 } 20 int sum(int i,int j){ 21 int tmpj,ans=0; 22 while(i>=1){ 23 tmpj=j; 24 while(tmpj>=1){ 25 ans+=tr[i][tmpj]; 26 tmpj-=lowbit(tmpj); 27 } 28 i-=lowbit(i); 29 } 30 return ans; 31 } 32 int main(){ 33 int op,n; 34 while(scanf("%d%d",&op,&n)!=EOF){ 35 row=col=n; 36 memset(tr,0,sizeof(tr)); //初始化树状数组 37 while(scanf("%d",&op)&&op!=3){ 38 if(op==1){ 39 int x,y,c; 40 scanf("%d%d%d",&x,&y,&c); 41 x++,y++; 42 add(x,y,c); 43 } 44 else{ 45 int x1,y1,x2,y2; 46 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 47 x1++,y1++,x2++,y2++; //记得将这些坐标+1 48 int ans=sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1); //sum(x,y)代表(1,1)到(x,y)这个子矩阵内所有元素之和 49 printf("%d\n",ans); 50 } 51 } 52 } 53 return 0; 54 }
2018-10-16
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。