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;
    }
  • 相关阅读:
    【SQL Server学习笔记】Service Broker创建异步的、数据驱动的消息应用程序
    记录几句不错的话
    DBA最缺的不是技术
    小数点引起的数据类型转换问题
    hdu 3062 2SAT最基础题
    POJ 1679 判断最小生成树是否唯一
    POJ 1459 构图+最大流(Edmond_karp模版)
    POJ 3522 最大边与最小边差值最小的生成树
    POJ 1659 根据度序列构图
    POJ 1273 求最大流(Edmond_karp模板题)
  • 原文地址:https://www.cnblogs.com/zhuanzhuruyi/p/5863774.html
Copyright © 2011-2022 走看看