洛谷U19464 山村游历(Wander)(LCT)

传送门

一起膜拜Flash Hu大佬

期望啥的我真的是一脸懵逼

这题我真的是连题解都写不来了……勉强能看懂而已……

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using std::swap;
 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 7 char buf[1<<21],*p1=buf,*p2=buf;
 8 inline int read(){
 9     #define num ch-'0'
10     char ch;bool flag=0;int res;
11     while(!isdigit(ch=getc()))
12     (ch=='-')&&(flag=true);
13     for(res=num;isdigit(ch=getc());res=res*10+num);
14     (flag)&&(res=-res);
15     #undef num
16     return res;
17 }
18 char obuf[1<<24],*o=obuf;
19 inline void print(int x){
20     if(x>9) print(x/10);
21     *o++=x%10+48;
22 }
23 inline void putsno(){*o++='I',*o++='L',*o++='L',*o++='E',*o++='G',*o++='A',*o++='L',*o++='\n';}
24 inline void putsyes(){*o++='O',*o++='K',*o++='\n';}
25 inline void putssa(){*o++='.',*o++='0',*o++='0',*o++='0',*o++='0',*o++='\n';}
26 const int N=100005;
27 int fa[N],ch[N][2],rev[N],st[N],s[N],si[N],top;
28 inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
29 inline void pushup(int x){s[x]=s[ch[x][0]]+s[ch[x][1]]+si[x]+1;}
30 inline void pushdown(int x){
31     if(x&&rev[x]){
32         swap(ch[x][0],ch[x][1]);
33         rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
34         rev[x]=0;
35     }
36 }
37 void rotate(int x){
38     int y=fa[x],z=fa[y],d=ch[y][1]==x;
39     if(!isroot(y)) ch[z][ch[z][1]==y]=x;
40     fa[x]=z,fa[y]=x,fa[ch[x][d^1]]=y,ch[y][d]=ch[x][d^1],ch[x][d^1]=y,pushup(y);
41 }
42 void splay(int x){
43     st[top=1]=x;for(int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
44     while(top) pushdown(st[top--]);
45     for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
46         if(!isroot(y))
47         ((ch[y][1]==x)^(ch[z][1]==y))?rotate(x):rotate(y);
48         rotate(x);
49     }
50     pushup(x);
51 }
52 void access(int x){
53     for(int y=0;x;x=fa[y=x])
54     splay(x),si[x]+=s[ch[x][1]],si[x]-=s[ch[x][1]=y],pushup(x);
55 }
56 void makeroot(int x){
57     access(x),splay(x),rev[x]^=1;
58 }
59 int findroot(int x){
60     access(x),splay(x);
61     while(ch[x][0]) x=ch[x][0];
62     return x;
63     /*splay的时候已经把标记全下传了,不用pushdown了(大概?)*/
64 }
65 void split(int x,int y){
66     makeroot(x),access(y),splay(y);
67 }
68 bool link(int x,int y){
69     makeroot(x);
70     if(findroot(y)==x) return false;
71     si[fa[x]=y]+=s[x];
72     pushup(y);
73     return true;
74 }
75 bool cut(int x,int y){
76     makeroot(x);
77     if(findroot(y)!=x||fa[x]!=y||ch[x][1]) return false;
78     fa[x]=ch[y][0]=0;
79     return true;
80 }
81 int main(){
82     //freopen("testdata.in","r",stdin);
83     int n=read(),q=read();
84     for(int i=1;i<=n;++i) s[i]=1;
85     while(q--){
86         int opt=read(),u=read(),v=read();
87         if(opt<2)puts((opt?cut(u,v):link(u,v))?"OK":"ILLEGAL");
88         else{
89             split(u,v);
90             if(findroot(v)!=u)puts("ILLEGAL");
91             else printf("%d.0000\n",s[v]-si[v]-1);
92             /*v已经被转到根了,且这条路径已经被拉出来了,已经是一个实子树了
93             直接算实子树大小(减掉t自己)*/
94         }
95     }
96     return 0; 
97 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9418308.html