제출 #963745

#제출 시각아이디문제언어결과실행 시간메모리
963745EJIC_B_KEDAXCat Exercise (JOI23_ho_t4)C++17
100 / 100
218 ms67416 KiB
#ifdef LOCAL
    #define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>

#ifndef LOCAL
    // #pragma GCC optimize("O3")
    // #pragma GCC optimize("Ofast")
    // #pragma GCC optimize("unroll-loops")
    // #pragma GCC target("avx,avx2,bmi,bmi2,popcnt,lzcnt")
#endif
using namespace std;
using ll = long long;
using ld = long double;
#define x first
#define y second
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

mt19937 mt(123);

void solve();
void init();

int32_t main() {
#ifndef LOCAL
    cin.tie(nullptr)->sync_with_stdio(false);
#endif
    cout << fixed << setprecision(30);
    init();
    int t = 1;
    // cin >> t;
    while (t--) {
        solve();
    }
}

void init() {}

const int LG = 18, N = 1 << LG;
int p[N], dsu[N], tin[N], tout[N], timer;
ll dp[N];
pair<int, int> binup[LG][N];
vector<int> g[N];

int get(int x) {
    return x == dsu[x] ? x : dsu[x] = get(dsu[x]);
}

void merge(int x, int y) {
    x = get(x);
    y = get(y);
    if (x < y) {
        swap(x, y);
    }
    dsu[y] = x;
}

void dfs(int s, int p = -1) {
    tin[s] = timer++;
    if (p == -1) {
        binup[0][s] = {0, s};
    } else {
        binup[0][s] = {1, p};
    }
    for (int i : g[s]) {
        if (i != p) {
            dfs(i, s);
        }
    }
    tout[s] = timer++;
}

bool check_pr(int i, int p) {
    return tin[p] <= tin[i] && tin[i] <= tout[p];
}

int get_dist(int u, int v) {
    int nw = u, res = 0;
    for (int l = LG - 1; l >= 0; l--) {
        if (!check_pr(v, binup[l][nw].y)) {
            res += binup[l][nw].x;
            nw = binup[l][nw].y;
        }
    }
    if (!check_pr(v, nw)) {
        res++;
    }
    nw = v;
    for (int l = LG - 1; l >= 0; l--) {
        if (!check_pr(u, binup[l][nw].y)) {
            res += binup[l][nw].x;
            nw = binup[l][nw].y;
        }
    }
    if (!check_pr(u, nw)) {
        res++;
    }
    return res;
}

void solve() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> p[i]; p[i]--;
        dsu[i] = i;
        dp[i] = 0;
    }
    for (int i = 0; i < n - 1; i++) {
        int u, v;
        cin >> u >> v; u--; v--;
        u = p[u];
        v = p[v];
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(0);
    for (int l = 1; l < LG; l++) {
        for (int i = 0; i < n; i++) {
            binup[l][i] = {binup[l - 1][i].x + binup[l - 1][binup[l - 1][i].y].x, binup[l - 1][binup[l - 1][i].y].y};
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j : g[i]) {
            if (j < i) {
                dp[i] = max(dp[i], dp[get(j)] + get_dist(i, get(j)));
            }
        }
        for (int j : g[i]) {
            if (j < i) {
                merge(i, j);
            }
        }
    }
    cout << dp[n - 1] << '\n';
}
#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...