3631:[JLOI2014]松鼠的新家

来源:互联网 发布:生鲜配送app源码 编辑:程序博客网 时间:2024/03/29 06:31

3631: [JLOI2014]松鼠的新家


树链剖分~~;

#include<bits/stdc++.h>#define rep(i,k,n) for(int i=k;i<=(n);i++)#define ls 2*x#define rs 2*x+1using namespace std;const int maxn=300005;struct E{    int to,next;    E(int to=0,int next=0):to(to),next(next){}}edge[2*maxn];int head[maxn],son[maxn],belong[maxn],cnt=0,top[maxn],dep[maxn],tot=0,lazy[4*maxn],a[maxn],val[maxn],ans[maxn],fa[maxn];void add(int x,int y){    edge[++tot]=E(y,head[x]);head[x]=tot;    edge[++tot]=E(x,head[y]);head[y]=tot;}int n;int dfs1(int u,int d){    dep[u]=d;    int ff=1,tmp,maxx=0;    for(int i=head[u];i;i=edge[i].next){        int v=edge[i].to;        if(v!=fa[u]){fa[v]=u;            tmp=dfs1(v,d+1);            if(tmp>maxx){maxx=tmp;son[u]=v;}            ff+=tmp;        }    }    return ff;}void dfs2(int u,int t){    belong[u]=++cnt;    val[cnt]=u;    top[u]=t;    if(son[u])dfs2(son[u],t);    for(int i=head[u];i;i=edge[i].next){        int v=edge[i].to;        if(v!=fa[u] && v!=son[u]){            dfs2(v,v);        }    }}void pushdown(int x,int l,int r){    if(l==r)return;    lazy[ls]+=lazy[x];    lazy[rs]+=lazy[x];    lazy[x]=0;}void update(int x,int l,int r,int ql,int qr){    pushdown(x,l,r);    if(l>=ql && r<=qr){lazy[x]++;return;    }    int mid=(l+r)>>1;    if(ql<=mid)update(ls,l,mid,ql,qr);    if(qr>mid)update(rs,mid+1,r,ql,qr);}void solve(int x,int y){    while(top[x]!=top[y]){        if(dep[top[x]]<dep[top[y]])swap(x,y);    ///        update(1,1,cnt,belong[top[x]],belong[x]);        x=fa[top[x]];    }    if(top[x]==top[y]){        if(dep[x]<dep[y])swap(x,y);        update(1,1,cnt,belong[y],belong[x]);    }}void getans(int x,int l,int r){    pushdown(x,l,r);    if(l==r){ans[val[l]]=lazy[x];return;}    int mid=(l+r)>>1;    getans(ls,l,mid);    getans(rs,mid+1,r);}int main(){//freopen("in.in","r",stdin);    scanf("%d",&n);    rep(i,1,n)scanf("%d",&a[i]);    int x,y;    fa[1]=1;    rep(i,1,n-1){        scanf("%d%d",&x,&y);        add(x,y);}        dfs1(1,1);        dfs2(1,1);    rep(i,1,n-1){        solve(a[i],a[i+1]);    }    getans(1,1,cnt);    rep(i,1,n){        if(i!=1)ans[a[i]]--;    }    rep(i,1,n)printf("%d\n",ans[i]);}
0 0