传送门:http://cogs.pro/cogs/problem/problem.php?pid=2089
第一眼看就是“银河英雄传说”,其实只是类似,异或和有神奇的地方。
首先,find时,只有fx!=find(fx)时,才更改sum[x],因为维护的是前缀和(感性理解),sum[x]不仅是自己的,而且异或了fx的,所以sum[x]不能多次更改,最后也要去掉f[x](就是多异或个fx)。
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; int n,m,a[300005],f[300005],sum[300005]; int read() { int sum=0,f=1;char x=getchar(); while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();} while(x>='0'&&x<='9')sum=sum*10+x-'0',x=getchar(); return sum*f; } int find(int x) { if(f[x]==x) return x; int k=find(f[x]); if(k!=f[x]) { sum[x]^=sum[f[x]]; f[x]=k; } return f[x]; } int main() { freopen("td.in","r",stdin); freopen("td.out","w",stdout); n=read();m=read(); for(int i=1;i<=n;i++) { sum[i]=a[i]=read(),f[i]=i; } int x,y,z; while(m--) { z=read(); if(z==1) { x=read(),y=read(); f[x]=y; } else { x=read(); find(x); if(f[x]==x)printf("%d ",sum[x]); else printf("%d ",sum[x]^sum[f[x]]); } } }