zoukankan      html  css  js  c++  java
  • POJ--2155(二维树状数组区间更新)

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

    题意:

    n*n的矩阵。初始为0。

    C:x1,y1,x2,y2:围成的矩阵内数字反转:0/1

    Q:x,y:查询a[x][y]为多少

    解析:

    还是差分

    先把它想成一维:修改[l,r]:那么我们就更新d[L]+1,d[R+1]+1;

    都+1的原因是,由于是取反,d[R+1]后面再加个1,就可以回复原状。

    接下来是二维:

    修改(x1,y1),那么从它到右下角,修改次数均+1 。涂颜色的部分是多余的部分,需要把它们回复原样。

    修改(x2+1,y1),(x1,y2+1),那么从它俩到右下角,修改次数加上上一步,为+2,也是恢复了原样。

    而(x1+1,y2+1)到右下角的部分+3了,要想恢复,需要再修改一次,变为偶数次修改+4,即恢复原样。

    由于本质上是个差分,所以要询问一个点,直接

    void update(int x,int y)
    {
        for(int i=x;i<maxn;i+=lowbit(i))
            for(int j=y;j<maxn;j+=lowbit(j))
                c[i][j]++;
    }

    一路加下来,得到的是a[i][j]本身的修改次数。

    总的ac代码,输出格式注意一下:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=1005;
    int c[maxn][maxn];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x,int y)
    {
        for(int i=x;i<maxn;i+=lowbit(i))
            for(int j=y;j<maxn;j+=lowbit(j))
                c[i][j]++;
    }
    int getsum(int x,int y)
    {
        int sum=0;
        for(int i=x;i>=1;i-=lowbit(i))
        {
            for(int j=y;j>=1;j-=lowbit(j))
                sum+=c[i][j];
        }
        return sum;
    }
    int getall(int x1,int y1,int x2,int y2)
    {
          return getsum(x2,y2)-getsum(x1-1,y2)-getsum(x2,y1-1)+getsum(x1-1,y1-1);
    }
    int main()
    {
          int t;
          cin>>t;
          while(t--)
          {
              int n,k;
             scanf("%d%d",&n,&k);
             memset(c,0,sizeof(c));
             char s[12];
            while(k--)
             {
                 scanf("%s",s);
                if(s[0]=='Q')
                {
                    int i , j ;
                    scanf("%d%d",&i,&j);
                    cout<<getsum(i,j)%2<<endl;
                }    
                else
                {
                    int x1,y1,x2,y2;
                    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                    update(x1,y1);
                    update(x2+1,y1);
                    update(x1,y2+1);
                    update(x2+1,y2+1);
                }
            }
            if(t>0)
                cout<<endl;
         }
    }
  • 相关阅读:
    基于策略模式简单实现element表单校验
    跨域
    原型模式
    单例模式
    vue-router进阶篇
    vue-router
    h5深度剖析
    js同步异步,任务队列
    JavaScript中事件委托(事件代理)详解
    网络请求get和post的区别
  • 原文地址:https://www.cnblogs.com/liyexin/p/13019757.html
Copyright © 2011-2022 走看看