【tricks】XOR-Hashing
一直没听说过这个玩意,做昨天牛客的时候想到异或的结论,但是就是卡在值冲突上了。
这类题大多是类似于对某些具有相同性质的元素统一修改,然后询问是否满足某一性质。
收集一些例题:
捏马,今年 CSP 考到了,结果我看不懂题就没做。
点击查看代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<random>
#include<ctime>
#include<algorithm>
using namespace std;
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
template <typename T>
inline void read(T& r) {
r=0;bool w=0; char ch=getchar();
while(ch<'0'||ch>'9') w=ch=='-'?1:0,ch=getchar();
while(ch>='0'&&ch<='9') r=(r<<3)+(r<<1)+(ch^48), ch=getchar();
r=w?-r:r;
}
#define pb push_back
const int N=5e5+10;
typedef long long ll;
int n,m,q;
ll val[N],f[N],s[N],all=0,now=0;
mt19937_64 rnd(time(0));
//f:到达其的被删除的点集合;s:到达其的点集合
//判断是否为基环外向树即为判断s的异或和与val的异或和是否相等
int main(){
read(n),read(m);
for(int i=1;i<=n;++i)val[i]=rnd(),f[i]=0,all^=val[i];
for(int i=1,u,v;i<=m;++i){
read(u),read(v);
s[v]^=val[u];now^=val[u];
}read(q);
for(int i=1,op,u,v;i<=q;++i){
read(op),read(u);
if(op==1)read(v),f[v]^=val[u],s[v]^=val[u],now^=val[u];
else if(op==2)f[u]^=s[u],now^=s[u],s[u]=0;
else if(op==3)read(v),f[v]^=val[u],s[v]^=val[u],now^=val[u];
else s[u]^=f[u],now^=f[u],f[u]=0;
now==all?printf("YES\n"):printf("NO\n");
}
return 0;
}