题意:初始n个冰岛独立,三种操作:
(1)判断A、B是否联通,当A、B不联通时输出yes并连接A、B,否则输出no
(2)把点A的点权改为x
(3)判断A、B是否联通,当A、B联通时输出从A到B的路径点权和否则输出impossible
没有cut的LCT基础题...
var
n,m,x,y :longint;
ch :char;
s :string;
flag :array[-1..30010] of boolean;
sum,father,w :array[-1..30010] of longint;
son :array[-1..30010,0..1] of longint;
i :longint;
procedure swap(var a,b:Longint);
var
c:longint;
begin
c:=a; a:=b; b:=c;
end;
function roott(x:longint):boolean;
begin
if (son[father[x],0]<>x) and (son[father[x],1]<>x) then exit(true) ;
exit(false);
end;
procedure update(x:longint);
begin
sum[x]:=sum[son[x,0]]+sum[son[x,1]]+w[x];
end;
procedure push_down(x:longint);
begin
if not roott(x) then push_down(father[x]);
if flag[x] then
begin
swap(son[x,0],son[x,1]);
if son[x,0]<>-1 then flag[son[x,0]]:=not flag[son[x,0]];
if son[x,1]<>-1 then flag[son[x,1]]:=not flag[son[x,1]];
flag[x]:=false;
end;
end;
procedure r_ro(f:longint);
var
x:longint;
begin
x:=son[f,0];
if (son[x,1]<>-1) then father[son[x,1]]:=f;
son[f,0]:=son[x,1];
if f=son[father[f],0] then son[father[f],0]:=x
else if f=son[father[f],1] then son[father[f],1]:=x;
father[x]:=father[f];
father[f]:=x;
son[x,1]:=f;
update(f); update(x);
end;
procedure l_ro(f:longint);
var
x:longint;
begin
x:=son[f,1];
if (son[x,0]<>-1) then father[son[x,0]]:=f;
son[f,1]:=son[x,0];
if f=son[father[f],1] then son[father[f],1]:=x
else if f=son[father[f],0] then son[father[f],0]:=x;
father[x]:=father[f];
father[f]:=x;
son[x,0]:=f;
update(f); update(x);
end;
procedure splay(x:longint);
begin
while not roott(x) do
if x=son[father[x],0] then r_ro(father[x])
else l_ro(father[x]);
end;
procedure access(x:longint);
var
y:longint;
begin
y:=-1;
while x<>0 do
begin
push_down(x);
splay(x);
son[x,1]:=y;
update(x);
y:=x; x:=father[x];
end;
end;
function find_root(x:longint):longint;
begin
access(x); splay(x);
while son[x,0]<>-1 do x:=son[x,0];
exit(x);
end;
procedure link(x,y:longint);
begin
access(x); splay(x); flag[x]:=not flag[x];
access(y); splay(y);
father[x]:=y;
son[y,1]:=x;
end;
begin
read(n);
for i:=1 to n do read(w[i]);
for i:=1 to n do sum[i]:=w[i];
fillchar(son,sizeof(son),255);
readln(m);
for i:=1 to m do
begin
s:='';
read(ch);
while (ch<>' ') do
begin
s:=s+ch;
read(ch);
end;
readln(x,y);
if s='bridge' then
begin
if find_root(x)<>find_root(y) then
begin
writeln('yes');
link(x,y);
end else writeln('no');
end else
if s='penguins' then
begin
w[x]:=y;
access(x);
end else
begin
if find_root(x)<>find_root(y) then writeln('impossible') else
begin
access(x);splay(x); flag[x]:=not flag[x];
access(y);splay(y);
writeln(sum[y]);
end;
end;
end;
end.
——by Eirlys