Submission #1069997

#TimeUsernameProblemLanguageResultExecution timeMemory
1069997WhisperCat Exercise (JOI23_ho_t4)C++17
100 / 100
184 ms68012 KiB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

#define int long long
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (b); i >= (a); i --)
#define REP(i, a) for (int i = 0; i < (a); ++i)
#define REPD(i, a) for (int i = (a) - 1; i >= 0; --i)

#define MASK(i) (1LL << (i))
#define BIT(x, i) (((x) >> (i)) & 1)


constexpr ll LINF = (1ll << 60);
constexpr int INF = (1ll << 30);
constexpr int Mod = 1e9 + 7;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

/*
    Phu Trong from Nguyen Tat Thanh High School for gifted student
*/

template <class X, class Y>
    bool minimize(X &x, const Y &y){
        X eps = 1e-9;
        if (x > y + eps) {x = y; return 1;}
        return 0;
    }

template <class X, class Y>
    bool maximize(X &x, const Y &y){
        X eps = 1e-9;
        if (x + eps < y) {x = y; return 1;}
        return 0;
    }
#define MAX                 200005
#define LOG                     19
vector<int> G[MAX];
int label[MAX], numNode;

int root = 1;


int up[MAX][LOG], depth[MAX];

void pre_dfs(int u, int p = -1){
    for (int &v : G[u]) if(v ^ p){
        up[v][0] = u;
        depth[v] = depth[u] + 1;

        for (int i = 1; i < LOG; ++i) up[v][i] = up[up[v][i - 1]][i - 1];
        pre_dfs(v, u);
    }
}
int low_bit(int p){
    return (p & (-p));
}
int lca(int u, int v){
    if (depth[u] < depth[v]) swap(u, v);
    int dis = depth[u] - depth[v];
    for (; dis > 0; dis ^= low_bit(dis)){
        int i = __builtin_ctz(low_bit(dis));
        u = up[u][i];
    }
    if(u == v) return u;

    for (int i = LOG - 1; i >= 0; --i) if(up[u][i] != up[v][i]){
        u = up[u][i], v = up[v][i];
    }
    return up[u][0];
}

int dis(int a, int b){
    return depth[a] + depth[b] - 2 * depth[lca(a, b)];
}


namespace SUBTASK_4{
    int dp[MAX], del[MAX];

    bool vis[MAX];
    int dfs(int u){
        vis[u] = true;

        int mx_node = u;
        for (int&v : G[u]) if(!vis[v]){
            if(del[v]) continue;
            int x = dfs(v);
            if(label[mx_node] < label[x]){
                mx_node = x;
            }
        }
        return mx_node;
    }
    void main(void){
        queue<int> q;
        q.emplace(root);
        while(q.size()){
            int u = q.front(); q.pop();
            if(del[u]) continue;
            del[u] = true;
            for (int&v : G[u]){
                memset(vis, 0, (numNode + 1) * sizeof(bool));
                int x = dfs(v);
                if(!del[x]){
                    if(maximize(dp[x], dp[u] + dis(x, u))){
                        q.push(x);
                    }
                }
            }
        }
        int ans = 0;
        for (int i = 1; i <= numNode; ++i) maximize(ans, dp[i]);
        cout << ans;
    }
}

namespace SUBTASK_7{

    int mx[MAX], pa[MAX];

    int find(int u){
        return u == pa[u] ? u : pa[u] = find(pa[u]);
    }

    bool joint(int u, int v){
        u = find(u), v = find(v);
        if(u == v) return false;

        if(mx[u] < mx[v]){
            swap(u, v);
        }
        pa[v] = u;
        maximize(mx[u], mx[v]);
        return true;
    }
    int dp[MAX];

    int ID[MAX];
    void main(void){
        for (int i = 1; i <= numNode; ++i) mx[i] = label[i], pa[i] = i, ID[label[i]] = i;

        memset(dp, 0, (numNode + 1) * sizeof(int));
        int ans = 0;
        for (int i = 1; i <= numNode; ++i){
            int u = ID[i];

            for (int&v : G[u]){
                if (label[v] < label[u]){
                    int prv = find(v);
                    maximize(dp[u], dp[prv] + dis(prv, u));
                    joint(v, u);
                }
            }
            maximize(ans, dp[u]);
        }
        cout << dp[ID[numNode]];
    }
}
void process(void){
    cin >> numNode;
    for (int i = 1; i <= numNode; ++i){
        cin >> label[i];
        if(label[i] == numNode) root = i;
    }
    for (int i = 1; i < numNode; ++i){
        int u, v; cin >> u >> v;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
    }
    pre_dfs(root, root);
    if(numNode <= 5000) {
        SUBTASK_4 :: main();
        return;
    }

    SUBTASK_7 :: main();
}
signed main(){
    #define name "Whisper"
    cin.tie(nullptr) -> sync_with_stdio(false);
    //freopen(name".inp", "r", stdin);
    //freopen(name".out", "w", stdout);
    process();
    return (0 ^ 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...