#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005;
const int LOG = 18;
const int inf = 1e9 + 7;
int n, d;
vector<int> g[maxn];
int jump[maxn][LOG];
int depth[maxn];
vector<int> tour;
void dfs(int node, int par, int d)
{
tour.push_back(node);
depth[node] = d;
jump[node][0] = par;
for (auto to : g[node])
{
if (to != par)
{
dfs(to, node, d + 1);
}
}
}
void buildSparse()
{
for (int log = 1; log < LOG; ++log)
{
for (int i = 1; i <= n; ++i)
{
jump[i][log] = jump[jump[i][log - 1]][log - 1];
}
}
}
int findLCA(int x, int y)
{
if (depth[x] < depth[y]) swap(x, y);
int diff = depth[x] - depth[y];
for (int i = 0; i < LOG; ++i)
{
if ((diff & (1 << i)) != 0)
{
x = jump[x][i];
diff -= (1 << i);
if (diff == 0) break;
}
}
if (x == y) return x;
for (int i = LOG - 1; i >= 0; --i)
{
if (jump[x][i] != jump[y][i])
{
x = jump[x][i];
y = jump[y][i];
}
}
return jump[x][0];
}
int dist(int x, int y)
{
int lca = findLCA(x, y);
return depth[x] + depth[y] - 2 * depth[lca];
}
int sz[maxn];
int parent[maxn];
bool seen[maxn];
void dfsInit(int node, int par)
{
sz[node] = 1;
for (auto to : g[node])
{
if (to != par && seen[to] == false)
{
dfsInit(to, node);
sz[node] += sz[to];
}
}
}
int findCentroid(int node, int par, int whole)
{
for (auto to : g[node])
{
if (to != par && seen[to] == false && sz[to] > whole / 2)
{
return findCentroid(to, node, whole);
}
}
return node;
}
int decompose(int node)
{
dfsInit(node, -1);
//cout << "decompose with " << node << " :: " << sz[node] << endl;
int c = findCentroid(node, -1, sz[node]);
seen[c] = true;
//cout << "found " << c << endl;
for (auto to : g[c])
{
if (seen[to] == false)
{
int newC = decompose(to);
parent[newC] = c;
}
}
return c;
}
int minDist[maxn];
void fastIO()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
int main()
{
fastIO();
cin >> n >> d;
for (int i = 2; i <= n; ++i)
{
int par;
cin >> par;
++par;
g[i].push_back(par);
g[par].push_back(i);
//cout << "edge " << i << " " << par << endl;
}
dfs(1, 1, 0);
buildSparse();
sort(tour.begin(), tour.end(), [&](int x, int y)
{
return depth[x] > depth[y];
});
for (int i = 1; i <= n; ++i)
{
parent[i] = -1;
minDist[i] = inf;
}
decompose(1);
/*for (int i = 1; i <= n; ++i)
{
cout << i << " :: " << parent[i] << endl;
}*/
int ans = 0;
for (auto node : tour)
{
int currentNode = node;
int currMin = inf;
while (currentNode != -1)
{
currMin = min(currMin, dist(node, currentNode) + minDist[currentNode]);
currentNode = parent[currentNode];
}
//cout << "on " << node << " -> " << currMin << endl;
if (currMin < d)
{
continue;
}
//cout << "mark " << node << endl;
++ans;
currentNode = node;
while (currentNode != -1)
{
minDist[currentNode] = min(minDist[currentNode], dist(node, currentNode));
currentNode = parent[currentNode];
}
}
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... |