bzoj 2002 LCT
LCT最基础的题,就用到了一个ACCESS操作
首先我们将这个绵羊弹飞的情况看成一颗树,那么假设X点被弹飞到
Y点,那么Y为X的父亲节点,弹飞的话父亲节点为n+1(虚设)
那么每个询问就是询问X点到根节点n+1的路径长度(节点数)
每个修改操作就是将以X为根节点的子树和X的父亲断开,连接到Y上
这样简单的维护森林连通性的问题,动态树中的LCT解决就行了
/************************************************************** Problem: 2002 User: BLADEVIL Language: Pascal Result: Accepted Time:2372 ms Memory:4328 kb ****************************************************************/ //By BLADEVIL var n, m :longint; father, size :array[-1..200010] of longint; son :array[-1..200010,0..2] of longint; root :array[-1..200010] of boolean; procedure update(x:longint); begin size[x]:=size[son[x,0]]+size[son[x,1]]+1; end; procedure left_rotate(x:longint); var y :longint; begin y:=son[x,1]; son[x,1]:=son[y,0]; father[son[x,1]]:=x; son[y,0]:=x; if x=son[father[x],0] then son[father[x],0]:=y else if x=son[father[x],1] then son[father[x],1]:=y; father[y]:=father[x]; father[x]:=y; root[y]:=root[x] xor root[y]; root[x]:=root[x] xor root[y]; update(x); update(y); end; procedure right_rotate(x:longint); var y :longint; begin y:=son[x,0]; son[x,0]:=son[y,1]; father[son[x,0]]:=x; son[y,1]:=x; if x=son[father[x],0] then son[father[x],0]:=y else if x=son[father[x],1] then son[father[x],1]:=y; father[y]:=father[x]; father[x]:=y; root[y]:=root[y] xor root[x]; root[x]:=root[y] xor root[x]; update(x); update(y); end; procedure splay(x:longint); begin while not root[x] do if x=son[father[x],1] then left_rotate(father[x]) else right_rotate(father[x]); end; procedure access(x:longint); var y :longint; begin splay(x); while father[x]<>0 do begin y:=father[x]; splay(y); root[son[y,1]]:=true; root[x]:=false; son[y,1]:=x; update(y); splay(x); end; end; procedure init; var i :longint; begin read(n); for i:=1 to n do begin read(father[i]); father[i]:=father[i]+i; if father[i]>n then father[i]:=n+1; end; read(m); end; procedure main; var i :longint; x, y, z :longint; begin for i:=1 to n+1 do size[i]:=1; fillchar(root,sizeof(root),true); for i:=1 to m do begin read(x); if x=1 then begin read(y); inc(y); access(y); writeln(size[son[y,0]]); end else begin read(y,z); inc(y); splay(y); father[son[y,0]]:=father[y]; root[son[y,0]]:=true; son[y,0]:=0; size[y]:=size[son[y,1]]+1; father[y]:=y+z; if father[y]>n then father[y]:=n+1; end; end; end; begin init; main; end.