POJ(1195)(单点修改,区间查询)(二维)

题目大意

给定一个N*N的网格,刚开始每个网格的值都是0,接下来会对这些网格进行操作,有一下两种操作:

1、”X Y A“对网格C[x][y]增加A

2、”L B R T“ 查询所有(L<=X<=R,B<=Y<=T)的网格],并返回它们的总和

如果是针对于单点修改,那是比区间修改好打很多,因为这个只需要将区间拆分成许多个树状数组就可以了,

然后修改的时候将树状数组修改,十分好理解的。

查询的话就是二维前缀和的查询,然后就可以了。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cmath>
 6 #define N 1057
 7 using namespace std;
 8 
 9 int n,k;
10 int a[N][N];
11 
12 int lowbit(int x)
13 {
14     return x&(-x);
15 }
16 void add(int x,int y,int z)
17 {
18     for (int i=x;i<=n;i+=lowbit(i))
19         for (int j=y;j<=n;j+=lowbit(j))
20             a[i][j]+=z;
21 }
22 int query(int x,int y)
23 {
24     int res=0;
25     for (int i=x;i>=1;i-=lowbit(i))
26         for (int j=y;j>=1;j-=lowbit(j))
27             res+=a[i][j];
28     return res;        
29 }
30 int main()
31 {
32     while(scanf("%d",&k))
33     {
34         if (k==0)
35         {
36             scanf("%d",&n);
37             for (int i=1;i<=n;i++)
38                 for (int j=1;j<=n;j++)
39                     a[i][j]=0;
40         }
41         if (k==1)
42         {
43             int x,y,z;
44             scanf("%d%d%d",&x,&y,&z);
45             x++,y++;
46             add(x,y,z);
47         }
48         if (k==2)
49         {
50             int x1,x2,y1,y2;
51             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
52             x1++,x2++,y1++,y2++;
53             cout<<query(x2,y2)+query(x1-1,y1-1)-query(x1-1,y2)-query(x2,y1-1)<<endl;
54         }
55         if (k==3) break;
56     }
57 }
原文地址:https://www.cnblogs.com/fengzhiyuan/p/7573275.html