zoukankan      html  css  js  c++  java
  • POJ 2155 Matrix(二维树状数组+区间更新单点求和)

      题意:给你一个n*n的全0矩阵,每次有两个操作: 
    C x1 y1 x2 y2:将(x1,y1)到(x2,y2)的矩阵全部值求反 
    Q x y:求出(x,y)位置的值

      树状数组标准是求单点更新区间求和,但是我们处理一下就可以完美解决此问题。区间更新可以使用区间求和的方法,在更新的(x2,y2)记录+1,在更新的(x1-1,y1-1)-1(向前更新到最前方)。单点求和就只需要与区间更新相反,向后求一个区间和。这样做的理由是:如果求和的点在某次更新范围内,我们+1但是不执行-1,否者要么都不执行,要么都执行就不变。 
      但是这儿我们是二维树状数组,我们需要使用容斥原理:(x2,y2)+1,(x1-1,y2)-1,(x2,y1-1)-1,(x1-1,y1-1)+1

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<stdlib.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define eps 1E-8
    /*注意可能会有输出-0.000*/
    #define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
    #define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
    #define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
    #define mul(a,b) (a<<b)
    #define dir(a,b) (a>>b)
    typedef long long ll;
    typedef unsigned long long ull;
    const int Inf=1<<28;
    const double Pi=acos(-1.0);
    const int Mod=1e9+7;
    const int Max=1010;
    int bit[Max][Max],n;
    void Init(int n)
    {
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
            bit[i][j]=0;
        return;
    }
    int lowbit(int x)
    {
        return x&(-x);
    }
    void Add(int x,int y,int z)
    {
        for(int i=x;i>0;i-=lowbit(i))
        {
            for(int j=y;j>0;j-=lowbit(j))
            {
                bit[i][j]=(bit[i][j]+z+2&1);
            }
        }
        return;
    }
    int Sum(int x,int y)
    {
        int sum=0;
        for(int i=x;i<=n;i+=lowbit(i))
        {
            for(int j=y;j<=n;j+=lowbit(j))
            {
                sum+=bit[i][j];
            }
        }
        return sum & 1;
    }
    int main()
    {
        int t,q,xx1,xx2,yy1,yy2;
        char str[10];
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d %d",&n,&q);
            Init(n);
            while(q--)
            {
                scanf("%s",str);
                if(str[0]=='C')
                {
                    scanf("%d %d %d %d",&xx1,&yy1,&xx2,&yy2);
                    Add(xx2,yy2,1);//区间更新的容斥原理
                    Add(xx1-1,yy2,-1);
                    Add(xx2,yy1-1,-1);
                    Add(xx1-1,yy1-1,1);
                }
                else
                {
                    scanf("%d %d",&xx1,&yy1);
                    printf("%d
    ",Sum(xx1,yy1));
                }
            }
            if(t)
                printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    win10安装.net3.5
    VS2015密钥
    wordpress目录文件结构说明
    js | javascript获取和设置元素的属性
    wordpress | WP Mail SMTP使用QQ邮箱发布失败的解决办法
    jquery 实时监听输入框值变化方法
    XPath编写规则学习
    如何将portfolio产品图片上的悬停去掉?
    wordpress怎么禁止文章复制
    js | javascript实现浏览器窗口大小被改变时触发事件的方法
  • 原文地址:https://www.cnblogs.com/zhuanzhuruyi/p/5863774.html
Copyright © 2011-2022 走看看