Submission #1107429

#TimeUsernameProblemLanguageResultExecution timeMemory
1107429Zero_OPCat Exercise (JOI23_ho_t4)C++14
54 / 100
115 ms53440 KiB
#include <bits/stdc++.h> using namespace std; template<typename T> bool maximize(T& a, const T& b){ if(a < b){ return a = b, true; } return false; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); #ifdef LOCAL freopen("task.inp", "r", stdin); freopen("task.out", "w", stdout); #endif // LOCAL struct DisjointSet{ vector<int> lab; DisjointSet(int n) : lab(n, -1) {} int root(int u){ return lab[u] < 0 ? u : (lab[u] = root(lab[u])); } bool unite(int u, int v){ u = root(u); v = root(v); if(u == v) return false; if(lab[u] > lab[v]) swap(u, v); lab[u] += lab[v]; lab[v] = u; return true; } }; int N; cin >> N; vector<int> P(N); for(int i = 0; i < N; ++i) cin >> P[i], --P[i]; vector<vector<int>> adj(N); for(int i = 1; i < N; ++i){ int u, v; cin >> u >> v; --u, --v; u = P[u]; v = P[v]; adj[u].push_back(v); adj[v].push_back(u); } int timerdfs = 0; vector<int> depth(N); vector<int> tin(N), tout(N); vector<vector<int>> lift(32 - __builtin_clz(N), vector<int>(N)); function<void(int, int)> dfs = [&](int u, int pre){ tin[u] = ++timerdfs; for(int v : adj[u]) if(v != pre){ depth[v] = depth[u] + 1; lift[0][v] = u; for(int i = 1; (1 << i) <= depth[v]; ++i) lift[i][v] = lift[i - 1][lift[i - 1][v]]; dfs(v, u); } tout[u] = timerdfs; }; auto inside = [&](int u, int v) -> bool{ return tin[u] <= tin[v] && tout[v] <= tout[u]; }; auto getLCA = [&](int u, int v) -> int{ if(inside(u, v)) return u; if(inside(v, u)) return v; for(int i = 31 - __builtin_clz(depth[u]); i >= 0; --i){ if(depth[u] >= (1 << i) && !inside(lift[i][u], v)){ u = lift[i][u]; } } return lift[0][u]; }; auto distance = [&](int u, int v) -> int{ return depth[u] + depth[v] - 2 * depth[getLCA(u, v)]; }; dfs(N - 1, -1); vector<int> dp(N), maxLabel(N); iota(maxLabel.begin(), maxLabel.end(), 0); DisjointSet dsu(N); for(int i = 1; i < N; ++i){ for(int j : adj[i]) if(j < i){ int mx = maxLabel[dsu.root(j)]; maximize(dp[i], dp[mx] + distance(mx, i)); dsu.unite(i, j); maxLabel[dsu.root(i)] = i; } } cout << dp[N - 1] << '\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...