[BZOJ3282] Tree

来源:互联网 发布:mac ape 打开格式 编辑:程序博客网 时间:2024/06/05 15:54

传送门

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

题目大意

0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。
1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
3:后接两个整数(x,y),代表将点X上的权值变成Y。

题解

LCT

const    maxn=300050;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,c:longint;procedure swap(var a,b:longint);var c:longint;begin c:=a; a:=b; b:=c; end;procedure update(a:longint);begin    if a=0 then exit;    sum[a]:=sum[son[a,1]] xor sum[son[a,2]] xor val[a];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]:=0;  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[a]:=c; fa[b]:=a;    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 cut(a,b:longint);begin    makeroot(a);    access(b);    //if son[b,1]=a then begin son[b,1]:=0; fa[a]:=0; end;    son[b,1]:=0; fa[a]:=0;    update(b);end;procedure work1(a,b:longint);begin    makeroot(a);    access(b);    writeln(sum[b]);end;procedure work2(a,b:longint);begin    if getroot(a)=getroot(b) then exit;    link(a,b);end;procedure work3(a,b:longint);begin    {makeroot(a); access(b);    if (son[b,1]=a)and(son[a,2]=0) then cut(a,b);}    if getroot(a)<>getroot(b) then exit;    cut(a,b);end;procedure work4(a,b:longint);begin    access(a);    val[a]:=b;    update(a);end;begin    readln(n,m);    val[0]:=0; sum[0]:=0;    for i:=1 to n do        begin readln(val[i]); sum[i]:=val[i]; son[i,1]:=0; son[i,2]:=0; fa[i]:=0; rev[i]:=0; end;    for i:=1 to m do        begin            readln(a,b,c);            case a of            0:work1(b,c);            1:work2(b,c);            2:work3(b,c);            3:work4(b,c);            end;        end;        end.
0 0
原创粉丝点击