您的位置:首页 > 其它

bzoj 1180 LCT

2017-04-18 20:58 176 查看
给出n个结点以及每个点初始时对应的权值wi。起始时点与点之间没有连边。有3类操作: 1、bridge A B:询问结点A与结点B是否连通。如果是则输出“no”。否则输出“yes”,并且在结点A和结点B之间连一条无向边。 2、penguins A X:将结点A对应的权值wA修改为X。
3、excursion A B:如果结点A和结点B不连通,则输出“impossible”。否则输出结点A到结点B的路径上的点对应的权值的和。给出q个操作,要求在线处理所有操作。数据范围:1<=n<=30000, 1<=q<=300000, 0<=wi<=1000。

LCT模板题...

var
n,m,x,y :longint;
i :longint;
ch :char;
s :string;
son :array[-1..30010,0..1] of longint;
father,sum :array[-1..30010] of longint;
flag :array[-1..30010] of boolean;
w :array[-1..30010] of longint;

procedure swap(var a,b:longint);
var
c:longint;
begin
c:=a; a:=b; b:=c;
end;

procedure update(x:longint);
begin
sum[x]:=sum[son[x,0]]+sum[son[x,1]]+w[x];
end;

function root(x:longint):boolean;
begin
if x=son[father[x],0] then exit(false);
if x=son[father[x],1] then exit(false);
exit(true);
end;

procedure renew(x:longint);
begin
flag[x]:=not flag[x];
end;

procedure push_down(x:longint);
begin
if flag[x] then
begin
swap(son[x,0],son[x,1]);
if son[x,0]<>-1 then renew(son[x,0]);
if son[x,1]<>-1 then renew(son[x,1]);
end;
flag[x]:=false;
end;

procedure push(x:longint);
begin
if not root(x) then push(father[x]);
push_down(x);
end;

procedure ro(x,y:longint);
var
f:longint;
begin
f:=father[x];
if son[x,y xor 1]<>-1 then father[son[x,y xor 1]]:=f;
son[f,y]:=son[x,y xor 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,y xor 1]:=f;
update(f);
update(x);
end;

procedure splay(x:longint);
var
u,v:longint;
begin
while not root(x) do
begin
if root(father[x]) then ro(x,ord(x=son[father[x],1])) else
begin
if x=son[father[x],0] then u:=-1 else u:=1;
if father[x]=son[father[father[x]],0] then v:=-1 else v:=1;
if u*v=1 then
begin
ro(father[x],ord(x=son
4000
[father[x],1]));
ro(x,ord(x=son[father[x],1]));
end else
begin
ro(x,ord(x=son[father[x],1]));
ro(x,ord(x=son[father[x],1]));
end;
end;
end;
update(x);
end;

procedure access(x:longint);
var
y:longint;
begin
y:=-1;
while x<>0 do
begin
push(x);
splay(x);
son[x,1]:=y;
update(x);
y:=x;
x:=father[x];
end;
end;

procedure link(x,y:longint);
begin
access(x); splay(x); renew(x);
access(y); splay(y);
son[y,1]:=x;
father[x]:=y;
update(y);
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;

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
read(ch); s:='';
while(ch<>' ') do
begin
s:=s+ch;
read(ch);
end;
if s='bridge' then
begin
readln(x,y);
if find_root(x)=find_root(y) then writeln('no') else
begin
writeln('yes');
link(x,y);
end;
end else
if s='penguins' then
begin
readln(x,y);
access(x); splay(x); renew(x);
w[x]:=y; update(x);
end else
begin
readln(x,y);
if find_root(x)<>find_root(y) then writeln('impossible') else
begin
access(x); splay(x); renew(x);
access(y); splay(y);
writeln(sum[y]);
end;
end;
end;
end.
——by Eirlys

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bzoj