【HDU 1892】 二维树状数组

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1892

题目大意:有很多方格,每个方格对应的坐标为(I,J),刚开始时每个格子里有1本书,然后让你统计一片区域有多少本书,还可以增加书和减少,移动书。

解题思路:

 和一维树状数组没撒子区别。一维扩展到二维而已。

 需要注意的两点是:1.x,y坐标从0开始,所以存储更新的时候坐标分别加1进行更新。因为0坐标会进入死循环。

                          2.区间求和的时候bit数组里面存的是它整个左下角的和,所以还要进行操作(即下面的find函数)让它表示的此位置的数目。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxn=1005;
 8 int  bit[maxn][maxn];
 9 
10 int lowbit(int x)
11 {
12     return x&(-x);
13 }
14 
15 void add(int x, int y, int val)
16 {
17     while(x<maxn)
18     {
19         int t=y;
20         while(t<maxn)
21         {
22             bit[x][t]+=val;
23             t+=lowbit(t);
24         }
25         x+=lowbit(x);
26     }
27 }
28 
29 int sum(int x, int y)
30 {
31     int ans=0;
32     while(x>0)
33     {
34         int t=y;
35         while(t>0)
36         {
37             ans+=bit[x][t];
38             t-=lowbit(t);
39         }
40         x-=lowbit(x);
41     }
42     return ans;
43 }
44 
45 int  find(int x,int y)
46 {
47     return sum(x,y)-sum(x-1,y)-sum(x,y-1)+sum(x-1,y-1);
48 }
49 
50 int main()
51 {
52     int  T, n, x1, x2, y1, y2, a, tcase=0;
53     char  ch[5];
54     cin >> T;
55     while(T--)
56     {
57         printf("Case %d:\n",++tcase);
58         scanf("%d",&n);
59         memset(bit,0,sizeof(bit));
60         for(int i=1; i<maxn; i++)
61             for(int j=1; j<maxn; j++)
62                 add(i,j,1);
63         for(int i=0; i<n; i++)
64         {
65             scanf("%s",ch);
66             if(ch[0]=='A'||ch[0]=='D')
67             {
68                 scanf("%d%d%d",&x1,&y1,&a);
69                 if(ch[0]=='D')
70                        a=-min(a,find(x1+1,y1+1));
71                 add(x1+1,y1+1,a);
72             }
73             else if(ch[0]=='M')
74             {
75                 scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&a);
76                 int  tmp=min(a,find(x1+1,y1+1));
77                 add(x1+1,y1+1,-tmp);
78                 add(x2+1,y2+1,tmp);
79             }
80             else
81             {
82                 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
83                 if(x1>x2) swap(x1,x2);
84                 if(y1>y2) swap(y1,y2);
85                 int  tmp=sum(x2+1,y2+1)-sum(x1,y2+1)-sum(x2+1,y1)+sum(x1,y1);
86                 printf("%d\n",tmp);
87             }
88         }
89     }
90     return 0;
91 }
原文地址:https://www.cnblogs.com/kane0526/p/2760349.html