This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
#define mp make_pair
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
#define chmin(a,b) a=min(a,b)
#define chmax(a,b) a=max(a,b)
#define MAX_N 200010
ll n,p[MAX_N],a[MAX_N],b[MAX_N];
vll g[MAX_N];
struct LCA{
    #define D 20
    ll depth[MAX_N],par[MAX_N][D];
    void dfs(ll x,ll from,ll d){
        depth[x]=d;
        par[x][0]=from;
        for(auto y:g[x])if(y!=from){
            dfs(y,x,d+1);
        }
    }
    void init(){
        dfs(0,0,0);
        rep(d,D-1){
            rep(i,n){
                par[i][d+1]=par[par[i][d]][d];
            }
        }
    }
    ll lca(ll a,ll b){
        if(depth[a]>depth[b])swap(a,b);
        assert(depth[a]<=depth[b]);
        for(ll d=D-1;d>=0;d--){
            if(depth[a]<=depth[b]-(1<<d)){
                b=par[b][d];
            }
        }
        assert(depth[a]==depth[b]);
        if(a==b)return a;
        for(ll d=D-1;d>=0;d--){
            if(par[a][d]!=par[b][d]){
                a=par[a][d];
                b=par[b][d];
            }
        }
        assert(a!=b);
        return par[a][0];
    }
    ll dist(ll a,ll b){
        ll c=lca(a,b);
        return depth[a]+depth[b]-2*depth[c];
    }
};
LCA lca;
struct UnionFind{
    ll par[MAX_N];
    void init(){
        rep(i,n){
            par[i]=i;
        }
    }
    ll root(ll x){
        return par[x]=(x==par[x]?x:root(par[x]));
    }
    void unite(ll a,ll b){
        a=root(a);
        b=root(b);
        if(a!=b){
            if(p[a]>p[b])swap(a,b);
            assert(p[a]<p[b]);
            par[a]=b;
        }
    }
};
UnionFind uf;
ll rp[MAX_N],f[MAX_N];
int main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cin>>n;
    rep(i,n){
        cin>>p[i];
        rp[p[i]]=i;
    }
    rep(i,n-1){
        cin>>a[i]>>b[i];
        a[i]--,b[i]--;
        g[a[i]].pb(b[i]);
        g[b[i]].pb(a[i]);
    }
    lca.init();
    uf.init();
    for(int i=1;i<=n;i++){
        ll x=rp[i];
        ll ans=0;
        for(auto y:g[x])if(p[y]<p[x]){
            ll v=uf.root(y);
            chmax(ans,f[v]+lca.dist(v,x));
            uf.unite(x,y);
        }
        f[x]=ans;
    }
    ll root=rp[n];
    ll ans=f[root];
    cout<<ans<<"\n";
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |