제출 #587406

#제출 시각아이디문제언어결과실행 시간메모리
587406MohamedAliSaidaneCat in a tree (BOI17_catinatree)C++14
100 / 100
449 ms47188 KiB
#include<bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; using namespace std; typedef tree<int,null_type,less<int>,rb_tree_tag, tree_order_statistics_node_update> indexed_set; typedef long long ll; typedef long double ld; ///#define int ll typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<ld,ld> pld; typedef vector<int> vi; typedef vector<ll> vll; typedef vector<pii> vpi; typedef vector<pll> vpl; #define pb push_back #define popb pop_back #define pp pop_back #define pf push_front #define popf pop_front #define all(x) (x).begin(),(x).end() #define ff first #define ss second int nx[4] = {0,0,1,-1}, ny[4] = {1,-1,0,0}; ll gcd(ll a , ll b) {return b ? gcd(b , a % b) : a ;} ll lcm(ll a , ll b) {return (a * b) / gcd(a , b);} const ll MOD = 998244353; const int nax = 2e5 + 4; int n, k; vi adj[nax]; vi lay[nax]; int d[nax], head[nax], minidis[nax], sp[nax][21], mark[nax], sz[nax]; void dfs(int x, int p) { d[x] = d[p] + 1; sp[x][0] = p; lay[d[x]].pb(x); for(auto e: adj[x]) if(e != p) dfs(e,x); } void build() { for(int j= 1; j < 20; j ++) for(int i = 1; i <= n; i ++) sp[i][j] = sp[sp[i][j-1]][j-1]; } int jump(int a, int k) { for(int i = 0; i < 20; i ++) if((1 << i) & k) a = sp[a][i]; return a; } int lca(int a, int b) { if(d[a] < d[b]) swap(a,b); a = jump(a, d[a] - d[b]); if(a == b) return a; for(int i= 19; i >= 0; i --) if(sp[a][i] != sp[b][i]) a = sp[a][i], b = sp[b][i]; return sp[a][0]; } int dist(int a, int b) { int c = lca(a,b); return d[a] + d[b] - 2 * d[c]; } int subtreesz(int x, int p) { sz[x] = 1; for(auto e: adj[x]) { if(e == p || mark[e]) continue; sz[x] += subtreesz(e,x); } return sz[x]; } int centroid(int x, int p, int s) { for(auto e: adj[x]) { if(e == p || mark[e]) continue; if(sz[e] > s/2) return centroid(e,x,s); } return x; } int get_centroid(int x) { ///cout << x << endl; x = centroid(x,0,subtreesz(x,0)); mark[x] = 1; for(auto e: adj[x]) { if(mark[e]) continue; int c = get_centroid(e); head[c] = x; } return x; } int compute(int x) { int mini = MOD/2; int cur = x; while(cur != 0) { mini = min(mini,minidis[cur] + dist(cur,x)); cur = head[cur]; } return mini; } void update(int x) { int cur = x; while(cur != 0) { minidis[cur] = min(minidis[cur], dist(cur,x)); cur = head[cur]; } } void solve() { cin >> n >> k; for(int a= 2 ; a <= n ;a ++) { int b; cin >> b; b ++ ; adj[a].pb(b); adj[b].pb(a); } d[0] = -1; dfs(1,0); build(); get_centroid(1); for(int i= 1 ; i <= n; i ++) minidis[i] = MOD/2; int ans = 0; for(int l= n - 1; l >= 0; l --) { for(auto e: lay[l]) { int mind = compute(e); if(mind >= k) { ans ++; update(e); } } } cout << ans; } int32_t main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int tt = 1; //cin >> tt; while(tt --) solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...