一起膜拜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++=' ';} 24 inline void putsyes(){*o++='O',*o++='K',*o++=' ';} 25 inline void putssa(){*o++='.',*o++='0',*o++='0',*o++='0',*o++='0',*o++=' ';} 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 ",s[v]-si[v]-1); 92 /*v已经被转到根了,且这条路径已经被拉出来了,已经是一个实子树了 93 直接算实子树大小(减掉t自己)*/ 94 } 95 } 96 return 0; 97 }