• poj2155(二维树状数组)


    我们知道二维数组,那么二维树状数组也是一个道理。

    第一维维护的是行,第二维维护的是行中的具体元素。

    空间O(n2),单次操作时间O((logn)2

    另本题实现的区间修改和单点查询需要用到差分的思想:

    看一维的情况,假设a数组:1,2,3,4,5

    b[i]=a[i]-a[i-1]:1,1,1,1,1

    则有a[i]=b[i]+b[i-1]+...+b[1]。

    对a数组的中间三个数加x,则b[i]:1,1+x,1,1,1-x,发现即只要b[l]+x,b[r+1]-x即可

    那么我们用树状数组维护b[i]数组即可。

    http://poj.org/problem?id=2155

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<map>
     8 #include<vector>
     9 #include<bitset>
    10 #define N 1005
    11 using namespace std;
    12 int sum[N][N],n;
    13 inline int lowbit(int x)
    14 {
    15     return (x&-x);
    16 }
    17 void change(int x,int y,int delta)
    18 {
    19     int ty=y;
    20     while(x<=n)
    21     {
    22         y=ty;
    23         while(y<=n)
    24         {
    25             sum[x][y]+=delta;
    26             y+=lowbit(y);
    27         }
    28         x+=lowbit(x);
    29     }
    30 }
    31 int query(int x,int y)
    32 {    int ty=y,ans=0;
    33     while(x>0)
    34     {    y=ty;
    35         while(y>0)
    36         {
    37             ans+=sum[x][y];
    38             y-=lowbit(y);
    39         }
    40         x-=lowbit(x);
    41     }
    42     return ans;
    43 }
    44 int main()
    45 {    
    46     int Case;
    47     cin>>Case;
    48     while(Case--)
    49     {
    50         memset(sum,0,sizeof sum);
    51         cin>>n;
    52         int q;
    53         cin>>q;
    54         while(q--)
    55         {
    56             char s[5];
    57             scanf("%s",s);
    58             if(s[0]=='C')
    59             {
    60                 int x1,x2,y1,y2;
    61                 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    62                 change(x1,y1,1);
    63                 change(x1,y2+1,-1);
    64                 change(x2+1,y1,-1);
    65                 change(x2+1,y2+1,1);
    66             }
    67             if(s[0]=='Q')
    68             {    int x,y;
    69                 scanf("%d%d",&x,&y); 
    70                 printf("%d
    ",query(x,y)&1);
    71             } 
    72         }
    73         if(Case!=0)
    74         printf("
    ");
    75     }
    76 
    77         
    78     return 0;
    79 } 
  • 相关阅读:
    终于以一个ACMer的名义开通博客了。。
    Struts学习笔记一
    Matplotlib画图
    设计模式第一集——策略模式
    Hibernate学习笔记
    在linux下加python path【转】
    linux学习笔记
    C#3.0初体验
    asp.net中使用ffmpeg
    常用的正则表达式(经典)
  • 原文地址:https://www.cnblogs.com/lnu161403214/p/9314705.html
Copyright © 2020-2023  润新知