Submission #961675

#TimeUsernameProblemLanguageResultExecution timeMemory
961675ThylOneCat Exercise (JOI23_ho_t4)C++14
100 / 100
300 ms59516 KiB
//####################
//CatExercise
//####################
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxiN = 200001;
vector<int> links[maxiN];
int dp[maxiN];
const int LOG = 20;
int depth[maxiN];
long long up[maxiN][LOG];
void dfs(int node,int papa=-1,int deep=0){
    up[node][0] = papa;
    depth[node] = deep;
    for(int v:links[node]){
        if(papa==v)continue;
        dfs(v,node,deep+1);
    }
}
void computeUp(int n){
    for(int l=1;l<LOG;l++){
        for(int i = 0;i<n;i++){
            if(up[i][l-1]==-1){
                up[i][l]=-1;
            }else{
                up[i][l] = up[up[i][l-1]][l-1];
            }
        }
    }
}
int jumpK(int a,int k){
    for(int l=0;l<LOG;l++){
        if((k>>l)&1){
            a = up[a][l];
        }
    }
    return a;
}
int lca(int a,int b){
    if(depth[a]<depth[b])swap(a,b);
    a = jumpK(a,depth[a]-depth[b]);
   
    if(a==b){
        return b;
    }
    for(int l=LOG-1;l>=0;l--){
        if(up[a][l]!=up[b][l]){
            a=up[a][l];
            b=up[b][l];
        }
    }
    return up[a][0];
}
int dist(int a,int b){
    int LCA = lca(a,b);
    return depth[a]+depth[b]-2*depth[LCA];
}
struct UnionFind{
    vector<int> chef;
    void init(int n){
        chef.resize(n);
        for(int i=0;i<n;i++){
            chef[i]=i;
        }
    }
    int find(int a){
        if(a==chef[a])return a;
        else return chef[a]=find(chef[a]);
    }
    void enraciner(int x,int r){
        if(find(x)==find(r)){
            return;
        }else{
            int fx = find(x);
            int fy = find(r);
            chef[fx] = fy;
        }
    }
};
signed main(){
    
    int n;cin>>n;
    int powers[n];
    for(int i = 0;i<n;i++){
        dp[i]=0;
        cin>>powers[i];
        powers[i]--;
    }
    for(int i= 0;i<n-1;i++){
        int a,b;cin>>a>>b;
        a--;b--;
        links[powers[a]].push_back(powers[b]);
        links[powers[b]].push_back(powers[a]);
    }
    dfs(0);
    computeUp(n);
    UnionFind UF;
    UF.init(n);
    for(int i = 0; i < n ; i++){
        dp[i] = 0;
        for(int voisin:links[i]){
            if(voisin>i)continue;
            int rep = UF.find(voisin); 
            dp[i] = max(dp[i], dp[rep]+dist(i,rep));
            UF.enraciner(voisin,i);
        }
    }
    cout<<dp[n-1]<<endl;
    
    return 0;
};
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...