제출 #223872

#제출 시각아이디문제언어결과실행 시간메모리
223872BruteforcemanCat in a tree (BOI17_catinatree)C++11
100 / 100
623 ms39524 KiB
#include <bits/stdc++.h> using namespace std; using pii = pair <int, int>; const int maxn = 2e5 + 10; vector <int> g[maxn]; int dep[maxn]; bool done[maxn]; int n, D; int anc[20][maxn]; const int logn = 19; const int inf = 1e9 + 7; int sub[maxn]; void flood(int x, int par, int dist) { if(dist == 0) return ; done[x] = true; for(auto i : g[x]) { if(i != par) { flood(i, x, dist - 1); } } } void dfs(int x, int par) { anc[0][x] = par == -1 ? 0 : par; for(int i = 1; i <= logn; i++) { anc[i][x] = anc[i - 1][anc[i - 1][x]]; } for(auto i : g[x]) { if(i != par) { dep[i] = 1 + dep[x]; dfs(i, x); } } } int lca(int x, int y) { if(dep[x] > dep[y]) swap(x, y); for(int i = logn; i >= 0; i--) { if(dep[y] - (1 << i) >= dep[x]) { y = anc[i][y]; } } if(x == y) return x; for(int i = logn; i >= 0; i--) { if(anc[i][x] != anc[i][y]) { x = anc[i][x]; y = anc[i][y]; } } return anc[0][y]; } int distance(int p, int q) { return dep[p] + dep[q] - 2 * dep[lca(p, q)]; } int dad[maxn]; bool vis[maxn]; int near[maxn]; void subtree(int x, int par) { sub[x] = 1; for(auto i : g[x]) { if(vis[i]) continue; if(i != par) { subtree(i, x); sub[x] += sub[i]; } } } int centroid(int x, int par, int range) { for(auto i : g[x]) { if(vis[i]) continue; if(i != par) { if(range < sub[i]) return centroid(i, x, range); } } return x; } int createTree(int x) { subtree(x, -1); x = centroid(x, -1, sub[x] / 2); vis[x] = true; near[x] = inf; for(auto i : g[x]) { if(!vis[i]) { dad[createTree(i)] = x; } } return x; } void add(int x) { int cur = x; while(cur != -1) { near[cur] = min(near[cur], distance(x, cur)); cur = dad[cur]; } return ; } int closest(int x) { int cur = x; int opt = inf; while(cur != -1) { opt = min(opt, distance(x, cur) + near[cur]); cur = dad[cur]; } return opt; } int main() { ios_base :: sync_with_stdio (false); cin.tie(0); cin >> n >> D; for(int i = 1; i < n; i++) { int x; cin >> x; g[x].emplace_back(i); g[i].emplace_back(x); } dfs(0, -1); // cout << distance(0, 3) << endl; vector <pii> v; for(int i = 0; i < n; i++) { v.emplace_back(dep[i], i); } sort(v.begin(), v.end(), greater <pii> ()); dad[createTree(0)] = -1; int ans = 0; for(auto i : v) { if(closest(i.second) < D) continue; add(i.second); ++ans; } cout << ans << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...