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

posted @ 2018-10-16 22:26  悠悠呦~  阅读(162)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end