[BZOJ1180] [CROATIAN2009]OTOCI

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=1180

题目大意

连边+单点修改+路径和

题解

LCT
终于意识到LCT的可怕之处了
细节!!!

const
    maxn=30000;
var
    son:array[0..maxn,1..2]of longint;
    fa,val,sum,rev:array[0..maxn]of longint;
    i,j,k:longint;
    n,m,a,b:longint;
    cha,ch:char;
procedure swap(var a,b:longint);
var c:longint;
begin c:=a; a:=b; b:=c; end;

procedure pushdown(a:longint);
begin
    if a=0 then exit;
    if rev[a]=0 then exit;
    swap(son[a,1],son[a,2]);
    if son[a,1]<>0 then rev[son[a,1]]:=rev[son[a,1]] xor 1;
    if son[a,2]<>0 then rev[son[a,2]]:=rev[son[a,2]] xor 1; 
    rev[a]:=rev[a] xor 1;
end;

procedure update(a:longint);
begin
    if a=0 then exit;
    sum[a]:=sum[son[a,1]]+sum[son[a,2]]+val[a];
end;

function isroot(a:longint):longint;
begin if (son[fa[a],1]<>a)and(son[fa[a],2]<>a) then exit(1) else exit(0); end;

procedure rotate(a,kind:longint);
var b,c,unkind:longint;
begin
    b:=fa[a]; c:=fa[b]; unkind:=kind xor 3;
    if son[c,1]=b then son[c,1]:=a else
    if son[c,2]=b then son[c,2]:=a; 
    fa[son[a,unkind]]:=b; son[b,kind]:=son[a,unkind]; son[a,unkind]:=b;
    fa[b]:=a; fa[a]:=c;
    update(b); update(a);
end;

procedure splay(a:longint);
var b,kind,unkind:longint;
begin
    pushdown(a); 
    while isroot(a)=0 do
        begin
            b:=fa[a]; pushdown(fa[b]); pushdown(b); pushdown(a);
            if son[b,1]=a then kind:=1 else kind:=2; unkind:=kind xor 3;
            if isroot(b)=1 then rotate(a,kind)
            else
                if son[fa[b],kind]=b
                then begin rotate(b,kind); rotate(a,kind); end
                else begin rotate(a,kind); rotate(a,unkind); end;
        end;
end;

procedure access(a:longint);
var b:longint;
begin
    splay(a); son[a,2]:=0; update(a);
    while fa[a]<>0 do
        begin
            b:=fa[a];
            splay(b);
            son[b,2]:=a; 
            update(b);
            splay(a);
        end;
end;

procedure makeroot(a:longint);
begin
    access(a);
    rev[a]:=rev[a] xor 1;
    pushdown(a);
end;

function getroot(a:longint):Longint;
begin
    access(a);
    while son[a,1]<>0 do
        a:=son[a,1];
    exit(a);
end;

procedure link(a,b:longint);
begin
    makeroot(a);
    fa[a]:=b;
end;

procedure work1(a,b:longint);
begin
    if getroot(a)=getroot(b)
    then writeln('no')
    else begin writeln('yes'); link(a,b); end;
end;

procedure work2(a,b:longint);
begin
    access(a);
    val[a]:=b;
    update(a);
end;

procedure work3(a,b:longint);
begin
    if getroot(a)<>getroot(b)
    then writeln('impossible')
    else begin makeroot(a); access(b); writeln(sum[b]); end;
end;

begin
    readln(n);
    for i:=1 to n do
        begin read(val[i]); sum[i]:=val[i]; son[i,1]:=0; son[i,2]:=0; fa[i]:=0; rev[i]:=0; end;
    readln(m);
    for i:=1 to m do
        begin
            read(cha,ch,ch,ch,ch,ch);
            case cha of
            'b':begin readln(a,b); work1(a,b); end;
            'p':begin readln(ch,ch,a,b); work2(a,b); end;
            'e':begin readln(ch,ch,ch,a,b); work3(a,b); end;
            end;
        end;
end.

你可能感兴趣的:([BZOJ1180] [CROATIAN2009]OTOCI)