bzoj4668 冷战
题目描述:
题解:
并查集按秩合并。
给并查集的边加上序号,每次查询时两个点就一起向上跳,最后剩下的就是答案。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 500050; template<typename T> inline void read(T&x) { T f = 1,c = 0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} x = f*c; } int n,m,ans,ff[N],siz[N],t[N]; int findff(int x){return ff[x]?findff(ff[x]):x;} void Merge(int x,int y,int tim) { if(siz[x]<siz[y])swap(x,y); ff[y] = x,t[y] = tim; if(siz[x]==siz[y])siz[x]++; } int Query(int x,int y) { while(ff[x]!=y&&ff[y]!=x) { if(t[x]<t[y])x=ff[x]; else y=ff[y]; } return ff[x]==y?t[x]:t[y]; } int main() { // freopen("tt.in","r",stdin); read(n),read(m); for(int i=1;i<=n;i++)siz[i]=1,t[i]=0x3f3f3f3f; for(int op,x,y,cnt=0,i=1;i<=m;i++) { read(op),read(x),read(y); x^=ans,y^=ans;////////////////////////////////////////////////////////////////// int fx = findff(x),fy = findff(y); if(!op) { cnt++; if(fx==fy)continue; Merge(fx,fy,cnt); }else { if(fx!=fy) { ans=0;puts("0"); continue; } ans = Query(x,y); printf("%d\n",ans); } } return 0; }