[BZOJ2631] tree

来源:互联网 发布:微信群如何做淘宝客 编辑:程序博客网 时间:2024/06/09 08:32

传送门

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

题目大意

支持
1.路径整体+c
2.路径整体*c
3.断边连边
4.路径和查询

题解

用这道题来整理一份LCT模板

{$M 100000000}const    maxn=100050;    mmod=51061;var    w:array[0..3*maxn,1..2]of longint;    son:array[0..maxn,1..2]of longint;    fa,rev,size,sum,val,add,mal:array[0..maxn]of longint;    i,j,k:longint;    n,m,a,b,c,d,len,tt:longint;    cha:char;procedure swap(var a,b:longint);var c:longint;begin c:=a; a:=b; b:=c; end;procedure init(a,b:longint);begin    w[len,1]:=b;    if w[a,2]=0 then w[a,2]:=len else w[w[a,1],2]:=len;    w[a,1]:=len; inc(len);end;procedure dfs(a:longint);var tt:longint;begin    tt:=w[a,2]; size[a]:=1; sum[a]:=1; val[a]:=1; add[a]:=0; mal[a]:=1; son[a,1]:=0; son[a,2]:=0; rev[a]:=0;    while tt<>0 do        begin            if w[tt,1]<>fa[a] then begin fa[w[tt,1]]:=a; dfs(w[tt,1]); end;            tt:=w[tt,2];        end;end;procedure update(a:longint);begin    if a=0 then exit;    size[a]:=size[son[a,1]]+size[son[a,2]]+1;    sum[a]:=(sum[son[a,1]]+sum[son[a,2]]+val[a])mod mmod;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 addd(a,b:longint);begin    if a=0 then exit;    val[a]:=(val[a]+b)mod mmod;    sum[a]:=(sum[a]+int64(b)*size[a])mod mmod;    add[a]:=(add[a]+b)mod mmod;end;procedure mall(a:longint;b:int64);begin    if a=0 then exit;    val[a]:=(b*val[a])mod mmod;    sum[a]:=(b*sum[a])mod mmod;    mal[a]:=(b*mal[a])mod mmod;    add[a]:=(b*add[a])mod mmod;end;procedure pushdown(a:longint);begin    if a=0 then exit;    if mal[a]<>1    then        begin            mall(son[a,1],int64(mal[a]));            mall(son[a,2],int64(mal[a]));            mal[a]:=1;                  end;    if add[a]<>0    then        begin            addd(son[a,1],add[a]);            addd(son[a,2],add[a]);            add[a]:=0;        end;    if rev[a]=1    then        begin            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;end;procedure rotate(a,kind:longint);var b,unkind:longint;begin    b:=fa[a]; unkind:=kind xor 3;    if son[fa[b],1]=b then son[fa[b],1]:=a else    if son[fa[b],2]=b then son[fa[b],2]:=a;    fa[a]:=fa[b];    son[b,kind]:=son[a,unkind]; fa[son[a,unkind]]:=b; son[a,unkind]:=b;    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);    splay(a);    rev[a]:=rev[a] xor 1;    pushdown(a);end;procedure link(a,b:longint);begin    makeroot(a);    fa[a]:=b;end;procedure cut(a,b:longint);begin    makeroot(a);    access(b);    son[b,1]:=0;    fa[a]:=0;    update(b);end;procedure work1(a,b,c:longint);begin    makeroot(a);    access(b);    addd(b,c);end;procedure work2(a,b,c,d:longint);begin    cut(a,b);    link(c,d);end;procedure work3(a,b,c:longint);begin    makeroot(a);    access(b);    mall(b,int64(c));end;procedure work4(a,b:longint);begin    makeroot(a);    access(b);    writeln(sum[b]);end;begin    readln(n,m); len:=n+1;    for i:=1 to n-1 do        begin            readln(a,b);            init(a,b); init(b,a);        end;    fa[1]:=0;    dfs(1);  tt:=0;    for i:=1 to m do        begin            read(cha);            case cha of            '+':begin readln(a,b,c); work1(a,b,c); end;            '-':begin readln(a,b,c,d); work2(a,b,c,d); end;            '*':begin readln(a,b,c); work3(a,b,c); end;            '/':begin readln(a,b); work4(a,b); end;            end;        end;end.
0 0
原创粉丝点击