제출 #990968

#제출 시각아이디문제언어결과실행 시간메모리
990968tincamateiCat Exercise (JOI23_ho_t4)C++14
100 / 100
171 ms45728 KiB
#include <bits/stdc++.h> struct DSU { std::vector<long long> height; std::vector<int> boss; explicit DSU(int N) { boss.resize(1 + N); height.resize(1 + N); for (int i = 1; i <= N; i++) boss[i] = i; } int find(int x) { if (x == boss[x]) return x; boss[x] = find(boss[x]); return boss[x]; } void merge(int a, int b) { int sa = find(a); int sb = find(b); if (sa > sb) boss[sb] = sa; else boss[sa] = sb; } }; struct DistanceCalculator { int lg = 0; std::vector<std::vector<int>>& graph; std::vector<std::vector<int>> parent; std::vector<int> dep; DistanceCalculator(std::vector<std::vector<int>>& _graph): graph(_graph) { int N = (int)graph.size() - 1; while ((1 << (lg + 1)) <= N) lg++; parent.resize(1 + N, std::vector<int>(1 + lg)); dep.resize(1 + N); predfs(); } void predfs(int node = 1, int father = 0) { parent[node][0] = father; for (int l = 1; l <= lg; l++) parent[node][l] = parent[parent[node][l - 1]][l - 1]; for (auto it: graph[node]) { if (it != father) { dep[it] = dep[node] + 1; predfs(it, node); } } } int goup(int node, int x) { for (int l = lg; l >= 0; --l) if ((1 << l) & x) node = parent[node][l]; return node; } int lca(int a, int b) { if (dep[a] > dep[b]) a = goup(a, dep[a] - dep[b]); else b = goup(b, dep[b] - dep[a]); if (a == b) return a; for (int l = lg; l >= 0; --l) if (parent[a][l] != parent[b][l]) { a = parent[a][l]; b = parent[b][l]; } return parent[a][0]; } int dist(int a, int b) { int l = lca(a, b); return dep[a] + dep[b] - 2 * dep[l]; } }; int main() { std::cin.tie(NULL); std::iostream::sync_with_stdio(false); int N; std::cin >> N; std::vector<int> perm(1 + N); for (int i = 1; i <= N; i++) std::cin >> perm[i]; std::vector<std::vector<int>> graph(1 + N); for (int i = 0; i < N - 1; i++) { int a, b; std::cin >> a >> b; a = perm[a]; b = perm[b]; graph[a].push_back(b); graph[b].push_back(a); } DSU dsu(N); DistanceCalculator dc(graph); //std::cerr << dc.dist(2, 3) << "\n"; for (int node = 1; node <= N; node++) { long long height = 0; for (auto it: graph[node]) { if (node > it) { height = std::max(height, dsu.height[dsu.find(it)] + dc.dist(node, dsu.find(it))); dsu.merge(node, it); } } dsu.height[dsu.find(node)] = height; //std::cerr << node << " has height " << height << "\n"; } std::cout << dsu.height[dsu.find(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...