Submission #1331050

#TimeUsernameProblemLanguageResultExecution timeMemory
1331050JuanJLCat Exercise (JOI23_ho_t4)C++20
31 / 100
2097 ms60020 KiB
#include <bits/stdc++.h>

#define fst first
#define snd second
#define pb push_back
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(),x.end()
#define forn(i,a,b) for(int i = a; i<b; i++)
#define mset(a,v) memset(a,v,sizeof(a))
#define FIN ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

using namespace std;
typedef long long ll;

const int MAXN = 200000+5;

#ifdef D
    #define debug(x) cout << x
#else
    #define debug(x) //nothing
#endif

ll n;
ll p[MAXN];
ll res[MAXN];
vector<ll> adj[MAXN];

struct UnionFind{
    ll n; 
    vector<ll> rep;
    vector<ll> sz;
    vector<set<pair<ll,ll>>> aadj;

    UnionFind(ll n) : n(n) , rep(n+5, 0), sz(n+5, 1) , aadj(n+5) {
        forn(i,0,n){
            rep[i]=i;
            for(auto j:adj[i]){
               aadj[i].insert({p[j],j});
            }
        }
    }

    ll Find(ll a){
        return rep[a]==a?a:rep[a]=Find(rep[a]);
    }

    void Union(ll a, ll b){

        debug("Union "<<a<<" "<<b<<'\n');

        ll pa = Find(a);
        ll pb = Find(b);

        if(pa==pb) return;

        if(sz[pa]<sz[pb]){
            rep[pa]=pb;
            for(auto i:aadj[pa]) aadj[pb].insert(i);
        }else{
            rep[pb]=pa;
            if(sz[pa]==sz[pb]){
                sz[pa]++;
            }
            for(auto i:aadj[pb]) aadj[pa].insert(i);
        }
    }
};

ll toJ;
ll lvlToJ;
ll dist[MAXN];
void dfs(ll nd , ll pa , ll val , ll lvl){
    dist[nd]=lvl;
    for(auto i:adj[nd]) if(i!=pa){
        dfs(i,nd,val,lvl+1);
    }
}

int main(){
    
    mset(res,0);

    cin>>n;
    forn(i,0,n) cin>>p[i];

    ll u,v;
    forn(i,0,n-1){
        cin>>u>>v; u--; v--;
        adj[u].pb(v);
        adj[v].pb(u);
    }

    vector<pair<ll,ll>> ord;
    forn(i,0,n){
        ord.pb({p[i],i});
    }
    sort(ALL(ord));

    UnionFind uf(n);

    forn(i,0,n-1){
        toJ=-1;
        lvlToJ=-1;

        ll nd = ord[i].snd;
        ll val = ord[i].fst;

        for(auto j:adj[nd]) if(p[j]<p[nd]){
            uf.Union(nd,j);
        }

        ll rep = uf.Find(nd);
        toJ = uf.aadj[rep].lower_bound({val+1,0})->snd;

        dfs(toJ,-1,0,0);
        lvlToJ=dist[nd];

        debug(i<<" "<<nd<<" "<<toJ<<" "<<rep<<" "<<lvlToJ<<'\n');
        debug(res[nd]<<'\n');

        res[toJ]=max(res[toJ], res[nd]+lvlToJ);
    }

    cout<<res[ord.back().snd]<<'\n';
    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...