首页 > 代码库 > poj 2155 二进制0 1反转---二维树状数组

poj 2155 二进制0 1反转---二维树状数组

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

上午自己搞了很久胡思乱想了很久,然后没思路-----看了论文《浅谈信息学竞赛中的“0”和“1”——二进制思想在信息学竞赛中的应用》,豁然开朗啊,,马上A掉---PE了一次o(╯□╰)o


通过论文学到的两点:
1、多维不会的时候,从一维尝试类比;

2、想法的证明,情况数不多的时候,分类讨论证明很好


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)

const int MAXN = 1000+100;
int c[MAXN][MAXN];int row,col;

inline int lowbit(int i){return i&(-i);}

void update(int x, int y,int v)
{
    while(x<=row)
    {
        int j=y;
        while(j<=col)
        {
            c[x][j]+=v;
            j+=lowbit(j);
        }
        x+=lowbit(x);
    }
}

int sum(int x, int y)
{
    int ret=0;
    while(x>0)
    {
        int j=y;
        while(j>0)
        {
            ret+=c[x][j];
            j-=lowbit(j);
        }
        x-=lowbit(x);
    }
    return ret;
}

int N;



int main()
{
    //IN("poj2155.txt");
    int ncase;
    int t,x1,x2,y1,y2,x,y;
    char op[30];
    scanf("%d",&ncase);
    while(ncase--)
    {
        CL(c,0);
        scanf("%d%d",&N,&t);
        col=row=N;
        while(t--)
        {
            scanf("%s",op);
            if(op[0] == 'C')
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                update(x1,y1,1);
                update(x1,y2+1,1);
                update(x2+1,y1,1);
                update(x2+1,y2+1,1);
            }
            if(op[0] == 'Q')
            {
                scanf("%d%d",&x,&y);
                printf("%d\n",sum(x,y)%2);
            }
        }
        putchar('\n');
    }
    return 0;
}