题意:给定一棵树,要求维护以下操作:
1.删除连接(x,y)的边
2.将(x,y)之间连边
3.询问某点子树大小
对于100%的数据n<=200000,m<=100000
思路:第一道有加边删边的LCT
讲一下自己对LCT各个操作的理解
Access:最基本的操作,将一个点到LCT的根的点全部修改为重(实)边
可以理解为“全选操作”,配合Splay操作可以取出某段区间的信息
Splay:将X旋转到它所在链的顶部,这样就相当于将这条链中的信息集中到了X这个点上
LCT的splay要用栈pushdown维护的原因是普通splay中splay操作前这些信息已经在Findkth的时候下传
而LCT没有,需要手动下传
Findroot:找到LCT的根,先Access+splay,因为LCT是按照深度维护的,所以一直往左走,找到深度最小的就是根
Makeroot:将X设置为LCT的根,Access+splay,因为上下翻转了所以要打翻转标记
Link:链接两个不在同一条链上的点,Makeroot(x),fa[x]=y
split:取出(x,y)这段区间的信息,Makeroot(x),Access(y),splay(y),信息在y点上
此题输出左儿子的子树大小即可
1 var t:array[0..500000,0..1]of longint; 2 next,fa,rev,size,q:array[0..500000]of longint; 3 n,m,i,x,y,tmp,top:longint; 4 5 function isroot(x:longint):boolean; 6 begin 7 if (t[fa[x],0]<>x)and(t[fa[x],1]<>x) then exit(true); 8 exit(false); 9 end; 10 11 procedure swap(var x,y:longint); 12 var t:longint; 13 begin 14 t:=x; x:=y; y:=t; 15 end; 16 17 procedure pushup(x:longint); 18 var l,r:longint; 19 begin 20 l:=t[x,0]; r:=t[x,1]; 21 size[x]:=size[l]+size[r]+1; 22 end; 23 24 procedure pushdown(x:longint); 25 var l,r:longint; 26 begin 27 l:=t[x,0]; r:=t[x,1]; 28 if rev[x]>0 then 29 begin 30 rev[x]:=rev[x] xor 1; rev[l]:=rev[l] xor 1; rev[r]:=rev[r] xor 1; 31 swap(t[x,0],t[x,1]); 32 end; 33 end; 34 35 procedure rotate(x:longint); 36 var y,z,l,r:longint; 37 begin 38 y:=fa[x]; z:=fa[y]; 39 if t[y,0]=x then l:=0 40 else l:=1; 41 r:=l xor 1; 42 while not isroot(y) do 43 begin 44 if t[z,0]=y then t[z,0]:=x 45 else t[z,1]:=x; 46 end; 47 fa[x]:=z; fa[y]:=x; fa[t[x,r]]:=y; 48 t[y,l]:=t[x,r]; t[x,r]:=y; 49 pushup(y); 50 pushup(x); 51 end; 52 53 procedure splay(x:longint); 54 var y,z,k:longint; 55 begin 56 inc(top); q[top]:=x; 57 k:=x; 58 while not isroot(k) do 59 begin 60 inc(top); q[top]:=fa[k]; 61 k:=fa[k]; 62 end; 63 while top>0 do 64 begin 65 pushdown(q[top]); 66 dec(top); 67 end; 68 69 while not isroot(x) do 70 begin 71 y:=fa[x]; z:=fa[y]; 72 if not isroot(y) then 73 begin 74 if (t[y,0]=x)xor(t[z,0]=y) then rotate(x) 75 else rotate(y); 76 end; 77 rotate(x); 78 end; 79 end; 80 81 procedure access(x:longint); 82 var last:longint; 83 begin 84 last:=0; 85 while x>0 do 86 begin 87 splay(x); t[x,1]:=last; //pushup(x); 88 last:=x; x:=fa[x]; 89 end; 90 end; 91 92 procedure makeroot(x:longint); 93 begin 94 access(x); splay(x); rev[x]:=rev[x] xor 1; 95 end; 96 97 procedure link(x,y:longint); 98 begin 99 makeroot(x); fa[x]:=y; 100 end; 101 102 procedure split(x,y:longint); 103 begin 104 makeroot(x); access(y); splay(y); 105 end; 106 107 procedure cut(x,y:longint); 108 begin 109 makeroot(x); access(y); splay(y); t[y,0]:=0; fa[x]:=0; 110 end; 111 112 function min(x,y:longint):longint; 113 begin 114 if x<y then exit(x); 115 exit(y); 116 end; 117 118 begin 119 assign(input,'bzoj2002.in'); reset(input); 120 assign(output,'bzoj2002.out'); rewrite(output); 121 readln(n); 122 for i:=1 to n do 123 begin 124 read(x); 125 fa[i]:=x+i; size[i]:=1; 126 if fa[i]>n then fa[i]:=n+1; 127 next[i]:=fa[i]; 128 end; 129 size[n+1]:=1; 130 readln(m); 131 for i:=1 to m do 132 begin 133 read(x); 134 case x of 135 1: 136 begin 137 read(y); inc(y); 138 split(n+1,y); 139 writeln(size[t[y,0]]); 140 end; 141 2: 142 begin 143 read(x,y); 144 inc(x); tmp:=min(x+y,n+1); 145 cut(x,next[x]); link(x,tmp); next[x]:=tmp; 146 end; 147 end; 148 end; 149 close(input); 150 close(output); 151 end.