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

 

 

你可能感兴趣的:(树状数组)