제출 #559292

#제출 시각아이디문제언어결과실행 시간메모리
559292SweezyCat in a tree (BOI17_catinatree)C++17
100 / 100
845 ms68316 KiB
#include <bits/stdc++.h> using namespace std; // #define int long long #ifdef LOCAL #include "algo/debug.h" #else #define debug(...) 42 #endif #define all(a) (a).begin(), (a).end() #define rep(i, n) for (int i = 0; i < (n); ++i) #define reps(i, s, n) for (int i = s; i < (n); ++i) #define pb push_back #define sz(a) (int) (a.size()) const int N = 2e5 + 5; const int inf = 1e9; vector<int> g[N]; vector<pair<int, int>> centroids[N]; int s[N], mdist[N], used[N], res, d, m; void sizes(int v, int p) { s[v] = 1; for (auto &u : g[v]) { if (u != p && !used[u]) { sizes(u, v); s[v] += s[u]; } } } int centroid(int v, int p, int n) { for (auto &u : g[v]) { if (u != p && !used[u] && s[u] > n / 2) { return centroid(u, v, n); } } return v; } void add_centroid(int v, int p, int centroid, int dist) { centroids[v].emplace_back(centroid, dist); for (auto &u : g[v]) { if (u != p && !used[u]) { add_centroid(u, v, centroid, dist + 1); } } } void decomposition1(int v) { used[v] = 1; sizes(v, -1); add_centroid(v, -1, v, 0); for (auto &u : g[v]) { if (!used[u]) { decomposition1(centroid(u, v, s[u])); } } } int vis[N], dis[N], q[N], from, to, vs[N]; void decomposition2(int v) { used[v] = 1; sizes(v, -1); m = 0; from = 0; to = 1; dis[v] = 0; q[0] = v; while (from != to) { int ver = q[from++]; vs[m++] = ver; vis[ver] = 1; for (auto &u : g[ver]) { if (!used[u] && !vis[u]) { dis[u] = dis[ver] + 1; q[to++] = u; vis[u] = 1; } } } // [v, vs]: 0 {(0, 0), (1, 1), (1, 2), (2, 3)} // [v, vs]: 1 {(0, 1), (1, 0), (1, 3), (2, 2)} // [v, vs]: 3 {(0, 3), (1, 1), (2, 0), (3, 2)} // [v, vs]: 2 {(0, 2), (1, 0), (2, 1), (3, 3)} // debug(v); // for (int i = 0; i < m; i++) { // cout << vs[i] << ' ' << dis[vs[i]] << '\n'; // } auto can = [&] (int ver) -> bool { for (auto &[centroid, dist_to_centroid] : centroids[ver]) { if (dist_to_centroid + mdist[centroid] < d) { return false; } } return true; }; int r = m, cnt = 0; rep(l, m) { while (r - 1 >= l && dis[vs[r - 1]] >= max(dis[vs[l]], d - dis[vs[l]])) { r--; int ver = vs[r]; if (can(ver)) { cnt++; for (auto &[centroid, dist_to_centroid] : centroids[ver]) { mdist[centroid] = min(mdist[centroid], dist_to_centroid); } } } if (l == r) { res = max(res, cnt); break; } else { res = max(res, cnt + can(vs[l])); } } for (int i = 0; i < m; i++) { for (auto &[centroid, dist_to_centroid] : centroids[vs[i]]) { mdist[centroid] = inf; } } for (auto &u : g[v]) { if (!used[u]) { decomposition2(centroid(u, v, s[u])); } } } void solve() { fill(mdist, mdist + N, inf); int n; cin >> n >> d; if (d > n - 1) { cout << 1; return; } if (d == 0) { cout << n; return; } reps(i, 1, n) { int p; cin >> p; g[p].push_back(i); g[i].push_back(p); } sizes(0, -1); decomposition1(centroid(0, -1, n)); fill(used, used + N, 0); sizes(0, -1); decomposition2(centroid(0, -1, n)); cout << res; } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); solve(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...