bzoj3631: [JLOI2014] squirrel home (differential trees)

Topic links: https://www.lydsy.com/JudgeOnline/problem.php?id=3631

Title effect: a given tree with n vertices, the entire tree of a given sequence order traveled a [1], a [2], [3] ...... a [n] a, from denotes a [1] go to a [2], and from a [2] went to a [3], until the come to a [n], the point right after the point a need to add, the final weight of each output point to point.

Problem-solving ideas: First, we take the time to discuss the case, assuming that come from t s, we can make ans [s] ++, ans [t] ++, ans [LCA (s, t)] -, and let LCA s and t father minus 1, and finally pushed, then the second node to the n-th node to walk once, and it is subtracted one.

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=300000+7;
int n,tot,a[maxn],head[maxn],fa[maxn][25],depth[maxn],ans[maxn];
struct Edge{
    int v,next;
}edge[maxn*2];
void add(int u,int v){
    edge[tot].v=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void dfs(int u,int pre){
    depth[u]=depth[pre]+1;
    fa[u][0]=pre;
    for(int i=1;i<=20;i++)
    fa[u][i]=fa[fa[u][i-1]][i-1];
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(v==pre) continue;
        dfs(v,u);
    }
}
int LCA(int u,int v){
    if(depth[u]<depth[v]) swap(u,v);
    for(int i=20;i>=0;i--){
        if(depth[u]-(1<<i)>=depth[v]) u=fa[u][i];
    }
    if(u==v) return u;
    for(int i=20;i>=0;i--){
        if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
    }
    return fa[u][0];
}
void dfs1(int u,int pre){
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(v==pre) continue;
        dfs1(v,u);
        ans[u]+=ans[v];
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    memset(head,-1,sizeof(head));
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v); add(v,u);
    }
    depth[0]=-1;
    dfs(1,0);
    for(int i=1;i<n;i++){
        ans[a[i]]++;
        ans[a[i+1]]++; 
        int lca=LCA(a[i],a[i+1]);
        ans[fa[lca][0]]--;
        ans[lca]--;
    }
    dfs1(1,0);
    for(int i=2;i<=n;i++)ans[a[i]]--;
    for(int i=1;i<=n;i++)
    printf("%d\n",ans[i]);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/zjl192628928/p/11277482.html