이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |