• 【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 }
  • 相关阅读:
    TCP通信 -C/S中的Socket与ServerSocket
    打印流 -可将数据写入文件/可改变输出方向
    转换流 -解决输入输出时编码格式不统一的问题
    字节/字符缓冲流
    Properties -IO相关的双列集合类
    IO流 -字符输入输出流,以及异常处理方法
    IO流
    线程间的通信
    o(* ̄︶ ̄*)o
    1
  • 原文地址:https://www.cnblogs.com/kane0526/p/2760349.html
Copyright © 2020-2023  润新知