又是一道卡常题..因为只有link没有cut,判断两点有没有联通另开一个并查集,用find_root会T...
lct维护,把环用并查集合并即可.
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=2e5+7;
15 typedef int LL;
16 typedef double db;
17 using namespace std;
18 int n,m;
19
20 template<typename T> void read(T &x) {
21 char ch=getchar(); x=0; T f=1;
22 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
23 if(ch=='-') f=-1,ch=getchar();
24 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
25 }
26
27 int fa[N],fa2[N];
28 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }
29
30 int find2(int x) { return x==fa2[x]?x:fa2[x]=find2(fa2[x]); }
31
32 int p[N],ch[N][2],flip[N];
33 LL sz[N],tsz[N],sum[N];
34 #define lc ch[x][0]
35 #define rc ch[x][1]
36 void update(int x) { sum[x]=sum[lc]+sum[rc]+sz[x]; }
37
38 void down(int x) {
39 if(!flip[x]) return;
40 swap(lc,rc);
41 flip[lc]^=1;
42 flip[rc]^=1;
43 flip[x]^=1;
44 }
45
46 int isroot(int x) { p[x]=find(p[x]); return ch[p[x]][0]!=x&&ch[p[x]][1]!=x; }
47
48 void rotate(int x) {
49 int y=find(p[x]),z=find(p[y]),l=(x==ch[y][1]),r=l^1;
50 if(!isroot(y)) ch[z][y==ch[z][1]]=x; p[x]=z;
51 ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
52 ch[x][r]=y; p[y]=x;
53 update(y); update(x);
54 }
55
56 void splay(int x) {
57 static int g[N],top=0,tp;
58 for(tp=x;!isroot(tp);tp=find(p[tp])) g[++top]=tp;
59 g[++top]=tp;
60 while(top) down(g[top--]);
61 for(;!isroot(x);rotate(x)) {
62 int y=find(p[x]),z=find(p[y]);
63 if(!isroot(y)) ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
64 }
65 }
66
67 void access(int x) {
68 for(int t=0;x;x=find(p[t=x])) {
69 splay(x);
70 rc=t;
71 update(x);
72 }
73 }
74
75 void newroot(int x) {
76 access(x);
77 splay(x);
78 flip[x]^=1;
79 }
80
81 void lik(int x,int y) {
82 newroot(x);
83 p[x]=y;
84 }
85
86 void change(int x,int y) {
87 splay(x);
88 sz[x]+=y;
89 update(x);
90 }
91
92 void qry(int x,int y) {
93 if(find2(x)!=find2(y)) {
94 puts("-1"); return;
95 }
96 newroot(x);
97 access(y);
98 splay(y);
99 printf("%d
",sum[y]);
100 }
101
102 LL tpsum=0;
103 void dfs(int x,int FA) {
104 tpsum+=sz[x];
105 fa[x]=FA;
106 if(lc) dfs(lc,FA);
107 if(rc) dfs(rc,FA);
108 }
109
110 void link_it(int x,int y) {
111 int u=find(x),v=find(y);
112 if(u==v) return;
113 if(find2(u)==find2(v)) {
114 newroot(u);
115 access(v);
116 splay(v);
117 tpsum=0;
118 dfs(v,v);
119 sz[v]=sum[v]=tpsum;
120 ch[v][0]=ch[v][1]=0;
121 }
122 else { lik(u,v); fa2[find2(u)]=find2(v); }
123 }
124
125 //#define DEBUG
126 int main() {
127 #ifdef DEBUG
128 freopen("1.in","r",stdin);
129 //freopen(".out","w",stdout);
130 #endif
131 read(n); read(m);
132 For(i,1,n) read(sz[i]),tsz[i]=sz[i],fa[i]=fa2[i]=i;
133 For(ti,1,m) {
134 int o,x,y;
135 read(o); read(x); read(y);
136 if(o==1) link_it(x,y);
137 else if(o==2) change(find(x),y-tsz[x]),tsz[x]=y;
138 else qry(find(x),find(y));
139 }
140 return 0;
141 }
//Achen #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<queue> #include<cmath> #include<ctime> #include<set> #define For(i,a,b) for(int i=(a);i<=(b);i++) #define Rep(i,a,b) for(int i=(a);i>=(b);i--) typedef long long LL; typedef double db; int vis[1000007],fa[100007],cnt[100008][11],ok[5007][5007]; using namespace std; int find(int x) { return x==fa[x]?x:find(fa[x]); } //#define DEBUG int main() { #ifdef DEBUG //freopen("line.in","r",stdin); freopen("std.in","w",stdout); #endif srand(time(0)); int n=500,m=1000,c=10,q=500; printf("%d %d %d %d ",n,m,c,q); For(i,1,n*c) fa[i]=i; For(i,1,n) { int x=rand()%10000+1; printf("%d ",x); } For(i,1,m) { int u,v,w; u=rand()%n+1; v=rand()%n+1; w=rand()%c; while(ok[u][v]||cnt[u][w]+1>2||cnt[v][2]+1>2||(find(w*n+u)==find(w*n+v))) { u=rand()%n+1; v=rand()%n+1; w=rand()%c; } ok[u][v]=1; fa[find(w*n+u)]=find(w*n+v); cnt[u][w]++; cnt[v][w]++; printf("%d %d %d ",u,v,w); } For(i,1,q) { int o=rand()%3; if(o==0) { int x=rand()%n+1,y=rand()%10000+1; printf("%d %d %d ",o,x,y); } else if(o==1) { int u=rand()%n+1,v=rand()%n+1,w=rand()%c; printf("%d %d %d %d ",o,u,v,w); } else { int w=rand()%c,u=rand()%n+1,v=rand()%n+1; while(u==v) { u=rand()%n+1; v=rand()%n+1; } printf("%d %d %d %d ",o,w,u,v); } } return 0; }