cogs2089 平凡的测试数据 并查集

链接:http://cogs.pro/cogs/problem/problem.php?pid=2089

题意:动态修改n个点之间关系,动态查询点到根路径权值异或和。

n<=300000,显然LCT(不会)和树剖会超时。要找到O(n)算法。

想到银河英雄传说一题对路径的处理,维护带权并查集,动态将各个集合合并并更新权值,查询时动态查询根节点

 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\n",weight[find(x)]^tot[x]);
38         }
39     }
40 }
41 int sb=haha();
42 int main(){;}
cogs 2089

 

即可。

注意:路径压缩完成时要更新权值。

posted @ 2017-07-25 21:33  ccc000111  阅读(197)  评论(0编辑  收藏  举报