제출 #782830

#제출 시각아이디문제언어결과실행 시간메모리
782830thimote75Cat Exercise (JOI23_ho_t4)C++14
100 / 100
451 ms72960 KiB
#include <bits/stdc++.h> #define int long long using namespace std; using idata = vector<int>; using igrid = vector<idata>; struct UFD { idata parents; UFD (int size) { parents.resize(size); iota(parents.begin(), parents.end(), 0); } int boss (int x) { if (parents[x] != x) parents[x] = boss(parents[x]); return parents[x]; } void merge (int a, int b) { a = boss(a); b = boss(b); if (a < b) swap (a, b); parents[b] = a; } }; const int MAXK = 20; int N; idata depth; idata parents; igrid parents_2k; igrid roads; void dfs (int node, int parent, int _depth) { depth [node] = _depth; parents [node] = parent; parents_2k[node][0] = parent; for (int next : roads[node]) if (next != parent) dfs(next, node, _depth + 1); } void init_lca () { for (int k = 0; k + 1 < MAXK; k ++) { for (int i = 0; i < N; i ++) { if (parents_2k[i][k] == -1) continue ; parents_2k[i][k + 1] = parents_2k[parents_2k[i][k]][k]; } } } int jump (int node, int k) { for (int i = 0; i < MAXK; i ++) if ((1 << i) & k) node = parents_2k[node][i]; return node; } int lca (int a, int b) { if (depth[a] > depth[b]) swap(a, b); b = jump(b, depth[b] - depth[a]); if (a == b) return a; for (int i = MAXK - 1; i >= 0; i --) { if (parents_2k[a][i] == parents_2k[b][i]) continue ; a = parents_2k[a][i]; b = parents_2k[b][i]; } return parents[a]; } int dist (int a, int b) { int l = lca(a, b); return depth[a] + depth[b] - 2 * depth[l]; } idata height; idata antiheight; signed main () { cin >> N; height.resize(N); antiheight.resize(N); for (int i = 0; i < N; i ++) { cin >> height[i]; height[i] --; antiheight[height[i]] = i; } roads.resize(N); for (int i = 1; i < N; i ++) { int a, b; cin >> a >> b; a --; b --; roads[a].push_back(b); roads[b].push_back(a); } depth .resize(N); parents.resize(N); parents_2k.resize(N, idata(MAXK, -1)); dfs(0, -1, 0); init_lca(); idata dp(N); UFD ufd(N); for (int i = 0; i < N; i ++) { int pos = antiheight[i]; int mdp = 0; for (int next : roads[pos]) { if (height[next] > i) continue ; int local = ufd.boss(height[next]); int ldp = dp [antiheight[local]] + dist(antiheight[local], pos); mdp = max(ldp, mdp); ufd.merge(i, height[next]); } dp[pos] = mdp; } cout << dp[antiheight[N - 1]] << endl; }
#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...