제출 #786851

#제출 시각아이디문제언어결과실행 시간메모리
786851tch1cherinCat Exercise (JOI23_ho_t4)C++17
51 / 100
2081 ms418276 KiB
#pragma GCC optimize("unroll-loops") #pragma GCC target("avx,avx2") #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/hash_policy.hpp> using namespace std; using namespace __gnu_pbds; struct custom_hash { size_t operator()(uint64_t x) const { return (x + 228) * 239; } }; const int MAX_N = 2e5 + 5; const int MAX_L = __lg(MAX_N) + 1; bitset<MAX_N> used_c, used_s; gp_hash_table<int, int> pos[MAX_N]; vector<int> graph[MAX_N], parent[MAX_N], dist[MAX_N]; vector<char> deleted[MAX_N]; int ancestors[MAX_N][MAX_L], num[MAX_N] = {}, value[MAX_N], sz[MAX_N]; struct cmp { bool operator()(const int& x, const int& y) const { return value[x] < value[y]; } }; set<int, cmp> values[MAX_N]; void find_sizes(int u, int p) { sz[u] = 1; for (int v : graph[u]) { if (v != p && !used_c[v]) { find_sizes(v, u); sz[u] += sz[v]; } } } int find_centroid(int u, int p, int n) { for (int v : graph[u]) { if (v != p && !used_c[v] && sz[v] > n / 2) { return find_centroid(v, u, n); } } return u; } void DFS(int u, int c, int p, int d) { pos[c][u] = (int)dist[c].size(); dist[c].push_back(d); parent[c].push_back(p); deleted[c].push_back(false); values[c].insert(u); ancestors[u][num[u]++] = c; for (int v : graph[u]) { if (v != p && !used_c[v]) { DFS(v, c, u, d + 1); } } } void centroid(int u) { find_sizes(u, -1); dist[u].reserve(sz[u]); parent[u].reserve(sz[u]); deleted[u].reserve(sz[u]); DFS(u, u, -1, 0); used_c[u] = true; for (int v : graph[u]) { if (!used_c[v]) { centroid(find_centroid(v, u, sz[v])); } } } void delete_subtree(int u, int p, int c) { values[c].erase(u); deleted[c][pos[c][u]] = true; for (int v : graph[u]) { if (v != p && pos[c].find(v) != pos[c].end() && !deleted[c][pos[c][v]]) { delete_subtree(v, u, c); } } } int64_t solve(int u) { used_s[u] = true; int64_t ans = 0; for (int i = 0; i < num[u]; i++) { int A = ancestors[u][i]; if (!deleted[A][pos[A][u]]) { delete_subtree(u, parent[A][pos[A][u]], A); } } for (int v : graph[u]) { if (!used_s[v]) { tuple<int, int, int> val = {-1, -1, -1}; for (int i = 0; i < num[v]; i++) { int A = ancestors[v][i]; if (!deleted[A][pos[A][v]] && !values[A].empty()) { int x = *values[A].rbegin(); val = max(val, {value[x], -(dist[A][pos[A][x]] + dist[A][pos[A][v]]), x}); } } ans = max(ans, solve(get<2>(val)) - get<1>(val) + 1); } } return ans; } int main() { cin.tie(nullptr)->sync_with_stdio(false); int N; cin >> N; for (int i = 0; i < N; i++) { cin >> value[i]; } for (int i = 0; i < N - 1; i++) { int u, v; cin >> u >> v; u--, v--; graph[u].push_back(v); graph[v].push_back(u); } find_sizes(0, -1); centroid(find_centroid(0, -1, N)); for (int i = 0; i < N; i++) { if (value[i] == N) { cout << solve(i) << "\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...