CF #439 E The Untended Antiquity

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<<endl
using 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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值