이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
//same as CSES 1752
using namespace std;
const int N = 200005;
vector<vector<int>> adj;
vector<int> order[N];
//lca
const int D = 18;
int n = INT_MIN;
int jump[N][D];
int depth[N];
int parent[N];
void initdfs(int v, int p){
   order[depth[v]].push_back(v);
   parent[v] = p;
   for(int nei : adj[v]){
      if(nei == p) continue;
      depth[nei] = depth[v]+1;
      jump[nei][0] = v;
      initdfs(nei,v);
   }
}
void initLCA() {
   for(int d = 1; d < D; d++) {
      for(int i = 1; i <= n; i++) {
         jump[i][d] = jump[jump[i][d-1]][d-1];
      }
   }
}
int getlca(int a, int b){
   if(depth[a] < depth[b]){
      swap(a,b);
   }
   
   for(int i = D-1; i >= 0; i--){
      if (((depth[a]-depth[b]) & (1<<i)) != 0){
         a = jump[a][i];
      }
   }
   if(a==b) return a;
   
   for(int i = D-1; i >= 0; i--){
      if(jump[a][i] != jump[b][i]){
         a = jump[a][i];
         b = jump[b][i];
      }
   }
   return jump[a][0];
}
int dist(int a, int b){
   return depth[a] + depth[b] - 2 * depth[getlca(a,b)];
}
int main(){
   ios::sync_with_stdio(false);
   cin.tie(0);
   
   int d;
   cin >> n >> d;
   
   adj = vector<vector<int>>(n+1,vector<int>());
   for(int k = 2; k <= n; k++){
      int a;
      cin >> a, a++;
      adj[a].push_back(k);
      adj[k].push_back(a);
   }
   
   for(int k = 0; k < n; k++) order[k] = vector<int>();
   
   initdfs(1,-1); 
   
   initLCA();
   
   //closest distance to other office in its subtree
   vector<int> closest(n+1,-1);
   vector<bool> covered(n+1,false);
   
   vector<int> answer;
   for(int h = N-1; h >= 0; h--){         //depth
      if(order[h].size() == 0) continue;
      
      int on = order[h].size();
      //left to right
      int r = 0;
      for(int k = 0; k < on; k++){
         int v = order[h][k];
         if(closest[v] == -1) continue;
         
         covered[v] = true;
         
         r = max(r,k+1);
         while(r < on && dist(v,order[h][r]) <= closest[v]){
            covered[order[h][r]] = true;
            r++;
         }
      }
      
      //right to left
      int l = on-1;
      for(int k = on-1; k >= 0; k--){
         int v = order[h][k];
         if(closest[v] == -1) continue;
         
         covered[v] = true;
         
         l = min(l,k-1);
         while(l >= 0 && dist(v,order[h][l]) <= closest[v]){
            covered[order[h][l]] = true;
            l--;
         }
      }
      
      int prev = -1;
      for(int k = 0; k < on; k++){
         int v = order[h][k];
         if(!(covered[v] || (prev != -1 && dist(prev,v) < d))){   
            answer.push_back(v);
            prev = v;
            closest[v] = d-1;
         }
         
         if(parent[v] != -1){
            closest[parent[v]] = max(closest[parent[v]],closest[v]-1);
         }
         
         
      }
   }
   
   cout << answer.size() << endl;
   //for(int i : answer) cout << i << " ";
   
   
   
   
   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... |