CF #439 E The Untended Antiquity

来源:互联网 发布:淘宝推广首选晨昊网络 编辑:程序博客网 时间:2024/06/11 07:59

CF #439 E The Untended Antiquity

随机化·二维BIT

题解:

添加一个矩形相当于为矩形内部的每个点都打上一个“在某个矩形内”的标记。

查询的时候只要查询两个点的标记序列是否完全一样就行了。

标记序列不好维护,直接把它变成一个数,类似于对它hash。

要求可以撤销,xor是一个不错的选择。加减好像也可以。

为了减少冲突,每个矩形的标记设为一个随机的unsigned long long

矩形区域加、删一个值很容易想到二维树状数组。

Code:

#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <map>#define D(x) cout<<#x<<" = "<<x<<"  "#define E cout<<endlusing namespace std;typedef unsigned long long ull;const int N = 2500;const ull Base = 1e5+7;int n,m,q;map<ull,ull> mp;struct BIT{    ull c[N+5][N+5];    inline int lowbit(int x){ return x&(-x); }    void add(int x,int y,ull d){        for(int i=x;i<=N;i+=lowbit(i))        for(int j=y;j<=N;j+=lowbit(j))            c[i][j] ^= d;    }    ull get(int x,int y){        ull res=0;        for(int i=x;i;i-=lowbit(i))        for(int j=y;j;j-=lowbit(j))            res ^= c[i][j];        return res;    }} bit;ull random(){ return (ull)rand()*rand()*rand(); }ull hash(ull a,ull b,ull c,ull d){ return a*Base*Base*Base + b*Base*Base + c*Base + d; }int main(){    freopen("5.in","r",stdin);    scanf("%d%d%d",&n,&m,&q);    ull d; int op,r1,c1,r2,c2;    while(q--){        scanf("%d%d%d%d%d",&op,&r1,&c1,&r2,&c2);        if(op==3){            if(bit.get(r1,c1) == bit.get(r2,c2)) puts("Yes");             else puts("No");            continue;        }        if(op==2){            d=mp[hash(r1,c1,r2,c2)];        }        if(op==1){            d=random();            mp[hash(r1,c1,r2,c2)]=d;        }//      D(op); D(r1); D(c1); D(r2); D(c2); D(d); E;        bit.add(r1,c1,d);        bit.add(r1,c2+1,d);        bit.add(r2+1,c1,d);        bit.add(r2+1,c2+1,d);    }}
阅读全文
0 0