Submission #782300

#TimeUsernameProblemLanguageResultExecution timeMemory
782300borisAngelovCat Exercise (JOI23_ho_t4)C++17
0 / 100
3 ms5076 KiB
#include <bits/stdc++.h> using namespace std; const int maxn = 200005; const int max_log = 18; const int inf = 1000000000; int n; vector<int> g[maxn]; int depth[maxn]; long long dp[maxn]; int permutation[maxn]; int jump[maxn][max_log]; void dfs(int node, int par, int dep) { depth[node] = dep; for (auto next_node : g[node]) { if (next_node != par) { jump[next_node][0] = node; dfs(next_node, node, dep + 1); } } } void build_sparse() { jump[1][0] = 1; for (int i = 1; i <= max_log - 1; ++i) { for (int j = 1; j <= n; ++j) { jump[j][i] = jump[jump[j][i - 1]][i - 1]; } } } int find_lca(int x, int y) { if (depth[x] < depth[y]) { swap(x, y); } int diff = depth[x] - depth[y]; for (int i = 0; i <= max_log - 1; ++i) { if ((diff & (1 << i)) != 0) { x = jump[x][i]; diff -= (1 << i); if (diff == 0) { break; } } } if (x == y) { return x; } for (int i = max_log - 1; i >= 0; --i) { if (jump[x][i] != jump[y][i]) { x = jump[x][i]; y = jump[y][i]; } } return jump[x][0]; } int find_dist(int x, int y) { return depth[x] + depth[y] - 2 * depth[find_lca(x, y)]; } int parent[maxn]; int dsu_rank[maxn]; int component_current_root[maxn]; int find_root(int node) { if (parent[node] == node) { return node; } return parent[node] = find_root(parent[node]); } void connect(int x, int y) { x = find_root(x); y = find_root(y); if (x == y) { return; } if (dsu_rank[x] < dsu_rank[y]) { swap(x, y); } if (dsu_rank[x] == dsu_rank[y]) { ++dsu_rank[y]; } parent[y] = x; } void fastIO() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); } int main() { fastIO(); cin >> n; for (int i = 1; i <= n; ++i) { cin >> permutation[i]; } for (int i = 1; i <= n - 1; ++i) { int x, y; cin >> x >> y; x = permutation[x]; y = permutation[y]; g[x].push_back(y); g[y].push_back(x); } dfs(1, -1, 0); for (int i = 1; i <= n; ++i) { dsu_rank[i] = 1; parent[i] = i; component_current_root[i] = i; } for (int node = 1; node <= n; ++node) { for (auto next_node : g[node]) { if (next_node > node) { continue; } dp[node] = max(dp[node], dp[component_current_root[find_root(next_node)]] + find_dist(node, component_current_root[find_root(next_node)])); connect(node, next_node); } component_current_root[find_root(node)] = node; } cout << dp[n] << endl; 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...