Submission #963745

#TimeUsernameProblemLanguageResultExecution timeMemory
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...