[BZOJ3631] [JLOI2014] 松鼠的新家

来源:互联网 发布:索尼耳机怎么样知乎 编辑:程序博客网 时间:2024/04/25 12:42

传送门

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

题目大意

给定一棵无根树和一个序列,在这个序列上依次遍历,求每个点的访问次数(最后一个点的访问次数要-1)

题解

树剖

const    maxn=300010;var    w:array[0..3*maxn,1..2]of longint;    bite,fa,son,size,dep,top,pos,x:array[0..maxn]of longint;    i,j,k:longint;    n,m,len,a,b:longint;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 dfs1(a:longint);var tt,v:longint;begin    tt:=w[a,2]; size[a]:=1; v:=0;    while tt<>0 do        begin            if w[tt,1]<>fa[a]            then                begin                    fa[w[tt,1]]:=a; dep[w[tt,1]]:=dep[a]+1;                    dfs1(w[tt,1]);                    inc(size[a],size[w[tt,1]]); if size[w[tt,1]]>size[v] then v:=w[tt,1];                end;            tt:=w[tt,2];        end;    son[a]:=v;end;procedure dfs2(a,pre:longint);var tt:longint;begin    tt:=w[a,2]; inc(len); pos[a]:=len; top[a]:=pre;    if son[a]<>0 then dfs2(son[a],pre);    while tt<>0 do        begin            if (w[tt,1]<>fa[a])and(w[tt,1]<>son[a]) then dfs2(w[tt,1],w[tt,1]);            tt:=w[tt,2];        end;end;procedure update(a,b:longint);begin    while a<=n+1 do        begin            inc(bite[a],b);            inc(a,a and (-a));        end;end;function query(a:longint):longint;var ans:longint;begin    ans:=0;    while a>0 do        begin            inc(ans,bite[a]);            dec(a,a and (-a));        end;    exit(ans);end;procedure change(a,b:longint);begin    update(pos[b],-1); update(pos[b]+1,1);    while top[a]<>top[b] do        begin            if dep[top[a]]<dep[top[b]] then swap(a,b);            update(pos[top[a]],1); update(pos[a]+1,-1);            a:=fa[top[a]];        end;    if dep[a]>dep[b] then swap(a,b);    update(pos[a],1); update(pos[b]+1,-1);end;begin    readln(n); len:=n+1;    for i:=1 to n do        read(x[i]);    for i:=1 to n-1 do        begin readln(a,b); init(a,b); init(b,a); end;    fa[1]:=0; dep[1]:=1; size[0]:=0;    dfs1(1);    len:=0;    dfs2(1,1);    for i:=1 to n-1 do        change(x[i],x[i+1]);    for i:=1 to n do        writeln(query(pos[i]));end.
0 0
原创粉丝点击