链接:http://cogs.pro/cogs/problem/problem.php?pid=2089
题意:动态修改n个点之间关系,动态查询点到根路径权值异或和。
n<=300000,显然LCT(不会)和树剖会超时。要找到O(n)算法。
想到银河英雄传说一题对路径的处理,维护带权并查集,动态将各个集合合并并更新权值,查询时动态查询根节点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<stack> 7 using namespace std; 8 const int maxn=300005; 9 int n,m,fa[maxn],tot[maxn],weight[maxn]; 10 int find(int x) 11 { 12 if(fa[x]==x)return x; 13 find(fa[x]); 14 tot[x]^=tot[fa[x]]; 15 fa[x]=fa[fa[x]]; 16 return fa[x]; 17 } 18 int haha() 19 { 20 freopen("td.in","r",stdin); 21 freopen("td.out","w",stdout); 22 scanf("%d%d",&n,&m); 23 for(int i=1;i<=n;i++)scanf("%d",&weight[i]); 24 for(int i=1;i<=n;i++)fa[i]=i; 25 for(int i=1;i<=m;i++) 26 { 27 int opt,x,y;scanf("%d",&opt); 28 if(opt==1) 29 { 30 scanf("%d%d",&x,&y); 31 tot[find(x)]=weight[fa[x]]; 32 fa[fa[x]]=y; 33 } 34 else 35 { 36 scanf("%d",&x); 37 printf("%d ",weight[find(x)]^tot[x]); 38 } 39 } 40 } 41 int sb=haha(); 42 int main(){;}
即可。
注意:路径压缩完成时要更新权值。