제출 #1271718

#제출 시각아이디문제언어결과실행 시간메모리
1271718Davdav1232Cat in a tree (BOI17_catinatree)C++20
0 / 100
21 ms37952 KiB
// Source: https://usaco.guide/general/io #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<int> vi; typedef vector<vi> vvi; int MAX_N=2e5+2; int n, d; vector<bool> vis_centroid(MAX_N, 0); vvi G(MAX_N); vi sz(MAX_N); ll ans=0; vi dep(MAX_N); vvi anc(MAX_N, vi(20)); int t=0; vi tin(MAX_N), tout(MAX_N); void dfs1(int node, int p){ t++; tin[node]=t; if(p==-1) dep[node]=0; else dep[node]=dep[p]+1; anc[node][0]=p; if(p!=-1){ int r=0; while(anc[anc[node][r]][r]!=-1){ anc[node][r+1]=anc[anc[node][r]][r]; r++; } while(r<19){ anc[node][r+1]=-1; } } for(int nei : G[node]){ if(nei == p) continue; dfs1(nei, node); } t++; tout[node]=t; } bool is_anc(int u, int v){ return (tin[u]<=tin[v] && tout[u]>=tout[v]); } int lca(int u, int v){ if(is_anc(u, v)) return u; int r=20; while(r>=1){ r--; if(anc[u][r]==-1 || is_anc(anc[u][r], v)) continue; u=anc[u][r]; } return anc[u][0]; } int distance(int u, int v){ return dep[u]+dep[v]-2*dep[lca(u, v)]; } int dfs(int node, int p=-1){ sz[node]=1; for(int neighbor : G[node]){ if(neighbor==p || vis_centroid[neighbor]) continue; sz[node]+=dfs(neighbor, node); } return sz[node]; } int find_centroid(int root){ dfs(root); int node=root; int p=-1; while(true){ bool ok=0; for(int neighbor : G[node]){ if(neighbor==p || vis_centroid[neighbor]) continue; if(2*sz[neighbor]>sz[root]){ p=node; node=neighbor; ok=1; break; } } if(!ok) break; } return node; } vi par(MAX_N); vi dist(MAX_N, 1e9); int root; vvi distances(MAX_N); int centroid_decomposition(int node){ int c=find_centroid(node); vis_centroid[c]=1; for(int neighbor: G[c]){ //find the number of paths of length k that pass through c if(vis_centroid[neighbor]) continue; par[centroid_decomposition(neighbor)]=c; } return c; } void mark(int node){ int u=node; int i=0; while(u!=-1){ if(distances[node][i]+dist[u]<d) return; u=par[u]; i++; } ans++; u=node; i=0; while(u!=-1){ dist[u]=min(dist[u], distances[node][i]); u=par[u]; i++; } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin>>n>>d; for(int i=1; i<n; i++){ int a; cin>>a; int b=i; G[a].push_back(b); G[b].push_back(a); } for (int i=0; i<n; i++){ for (int j=0; j<20; j++){ anc[i][j] = -1;}} dfs1(0, -1); root=centroid_decomposition(0); par[root]=-1; vector<pair<int, int>> depths; for(int i=0; i<n; i++){ depths.push_back({-dep[i], i}); } sort(depths.begin(), depths.end()); for(int i=0; i<n; i++){ int u=i; while(u!=-1){ distances[i].push_back(distance(i, u)); u=par[u]; } } for(int i=n-1; i>=0; i--){ mark(depths[i].second); } cout<<ans; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...