【tricks】XOR-Hashing

link

一直没听说过这个玩意,做昨天牛客的时候想到异或的结论,但是就是卡在值冲突上了。

这类题大多是类似于对某些具有相同性质的元素统一修改,然后询问是否满足某一性质。

收集一些例题:

CF1175F

CF1418G

CF895C

CF869E

CF1622F

ABC250E

P4065 [JXOI2017]颜色

捏马,今年 CSP 考到了,结果我看不懂题就没做。

P8819 [CSP-S 2022] 星战

点击查看代码
#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;
}
posted @ 2022-11-07 08:54  RuntimeErr  阅读(226)  评论(1编辑  收藏  举报