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);
}
}