Submission #223872

#TimeUsernameProblemLanguageResultExecution timeMemory
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...