标签:git root puts mes ble while and lse srand
题目描述
题解
因为这道题有删边和加边的操作,所以我们不能再链上操作,只能在点上操作。
考虑一些正确性玄学的算法。
我们给每一次链加随机一个权值,这样对于每次询问就查一下这条边分成的两块中的权值异或和是否等于当前所有链的权值异或和即可。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #define ls ch[x][0] #define rs ch[x][1] #define N 100009 using namespace std; int ch[N][2],sum,size[N],si[N],a[N],fa[N],n,m,top; bool rev[N]; inline int rd(){ int x=0;char c=getchar();bool f=0; while(!isdigit(c)){if(c==‘-‘)f=1;c=getchar();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} return f?-x:x; } inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} inline bool ge(int x){return ch[fa[x]][1]==x;} inline void pushup(int x){size[x]=size[ls]^size[rs]^si[x]^a[x];} inline void rotate(int x){ int y=fa[x],o=ge(x); ch[y][o]=ch[x][o^1];fa[ch[y][o]]=y; if(!isroot(y))ch[fa[y]][ge(y)]=x;fa[x]=fa[y]; fa[y]=x;ch[x][o^1]=y;pushup(y);pushup(x); } void pushdown(int x){if(rev[x])rev[ls]^=1,rev[rs]^=1,rev[x]^=1,swap(ls,rs);} void _pushdown(int x){if(!isroot(x))_pushdown(fa[x]);pushdown(x);} inline void splay(int x){ _pushdown(x); while(!isroot(x)){ int y=fa[x]; if(isroot(y))rotate(x); else rotate(ge(x)==ge(y)?y:x),rotate(x); } } inline void access(int x){ for(int y=0;x;y=x,x=fa[x]){ splay(x); si[x]^=size[y];si[x]^=size[ch[x][1]]; ch[x][1]=y; pushup(x); } } inline void makeroot(int x){access(x);splay(x);rev[x]^=1;} inline void split(int x,int y){makeroot(x);access(y);splay(y);} inline void link(int x,int y){ split(x,y); fa[x]=y;si[y]^=size[x];pushup(y); } inline void cut(int x,int y){ split(x,y); ch[y][0]=fa[x]=0; pushup(y); } struct node{int u,v,w;}st[N*3]; int main(){ int id=rd(); srand(19260928); n=rd();m=rd(); int x,y,u,v,w; for(int i=1;i<n;++i){ x=rd();y=rd(); link(x,y); } while(m--){ int opt=rd(); if(opt==1){ x=rd();y=rd();u=rd();v=rd(); cut(x,y);link(u,v); } else if(opt==2){ x=rd();y=rd();w=rand();sum^=w; st[++top]=node{x,y,w}; makeroot(y); a[y]^=w;pushup(y); access(x);splay(x); a[x]^=w;pushup(x); } else if(opt==3){ x=rd();sum^=st[x].w;u=st[x].u;v=st[x].v; makeroot(v); a[v]^=st[x].w;pushup(v); access(u);splay(u); a[u]^=st[x].w;pushup(u); } else{ x=rd();y=rd(); split(x,y); if((size[y]^size[x])!=sum){puts("NO");continue;} if(size[x]!=sum){puts("No");continue;} puts("YES"); } } return 0; }
标签:git root puts mes ble while and lse srand
原文地址:https://www.cnblogs.com/ZH-comld/p/10421533.html