SPOJ - OTOCI(LCT裸题)

题目链接:SPOJ - OTOCI

题意:

给你n个点,有三种操作。

1 将 x y 连接 如果已经连接了,就输出no,否则输出yes

2 将x的权值改为y

3 输出x到y的路径经过的所有点的权值。

题解:

LCT的题,很裸。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;i++)
 3 #define mst(a,b) memset(a,b,sizeof(a))
 4 using namespace std;
 5 
 6 namespace LCT
 7 {
 8     const int N=1e5+7;
 9     int f[N],son[N][2],val[N],sum[N],tmp[N],lazy[N];
10     int g[N],v[N*2],nxt[N*2],ed;bool rev[N];
11     void clear(int n)
12     {
13         F(i,1,n)f[i]=son[i][0]=son[i][1]=0;
14         F(i,1,n)rev[i]=lazy[i]=g[i]=0;ed=0;
15     }
16     void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
17     void build(int x=1){
18         sum[x]=val[x];
19         for(int i=g[x];i;i=nxt[i])
20             if(!f[v[i]]&&v[i]!=1)f[v[i]]=x,build(v[i]);    
21     }
22     bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
23     void rev1(int x){if(!x)return;swap(son[x][0],son[x][1]);rev[x]^=1;}
24     void add(int x,int c){if(!x)return;sum[x]+=c,val[x]+=c,lazy[x]+=c;}
25     void pb(int x){
26         if(rev[x])rev1(son[x][0]),rev1(son[x][1]),rev[x]=0;
27         if(lazy[x])add(son[x][0],lazy[x]),add(son[x][1],lazy[x]),lazy[x]=0;
28     }
29     void up(int x){
30         sum[x]=val[x];
31         if(son[x][0])sum[x]+=sum[son[x][0]];
32         if(son[x][1])sum[x]+=sum[son[x][1]];
33     }
34     void rotate(int x){
35         int y=f[x],w=son[y][1]==x;
36         son[y][w]=son[x][w^1];
37         if(son[x][w^1])f[son[x][w^1]]=y;
38         if(f[y]){
39             int z=f[y];
40             if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
41         }
42         f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
43     }
44     void splay(int x){
45         int s=1,i=x,y;tmp[1]=i;
46         while(!isroot(i))tmp[++s]=i=f[i];
47         while(s)pb(tmp[s--]);
48         while(!isroot(x)){
49             y=f[x];
50             if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
51             rotate(x);
52         }
53         up(x);
54     }
55     void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),son[x][1]=y,up(x);}
56     int root(int x){access(x);splay(x);while(son[x][0])x=son[x][0];return x;}
57     void makeroot(int x){access(x);splay(x);rev1(x);}
58     void link(int x,int y){makeroot(x);f[x]=y;access(x);}
59     void cutf(int x){access(x);splay(x);f[son[x][0]]=0;son[x][0]=0;up(x);}
60     void cut(int x,int y){makeroot(x);cutf(y);}
61     void update(int x,int y,int c){makeroot(x),access(y),splay(y),add(y,c);}
62     int ask(int x,int y){makeroot(x);access(y);splay(y);return sum[y];}
63 }
64 using namespace LCT;
65 int n,x,y,q;
66 char op[40];
67 
68 int main()
69 {
70     scanf("%d",&n);
71     F(i,1,n)scanf("%d",val+i);
72     build(),scanf("%d",&q);
73     while(q--)
74     {
75         scanf("%s%d%d",op,&x,&y);
76         if(*op=='e')
77         {
78             if(root(x)!=root(y))puts("impossible");
79             else printf("%d\n",ask(x,y));
80         }
81         else if(*op=='b')
82         {
83             if(root(x)!=root(y))link(x,y),puts("yes");
84             else puts("no");
85         }
86         else 
87         {
88             makeroot(x);
89             sum[x]-=val[x];
90             val[x]=y,sum[x]+=y;
91         }
92     }
93     return 0;
94 }
View Code

 

posted @ 2017-10-19 19:02  bin_gege  阅读(175)  评论(0编辑  收藏  举报