Submission #493544

#TimeUsernameProblemLanguageResultExecution timeMemory
493544nohaxjustsofloCat in a tree (BOI17_catinatree)C++17
100 / 100
213 ms34768 KiB
#include <bits/stdc++.h> #include <iostream> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; typedef tree<ll,null_type,less_equal<ll>,rb_tree_tag,tree_order_statistics_node_update> order_set; //mt19937 mt_rand(chrono::high_resolution_clock::now().time_since_epoch().count()); //uniform_int_distribution<int> gen; ///(min, max) //int random() {return gen(mt_rand);} const int mxN = 5e5+5; const int mod = 998244353; const int mxlogN = 20; const int mxK = 26; const ll inf = 1e9; vector<int> adj[mxN]; int down[mxN]; int p[mxN]; int in[mxN], out[mxN], _timer; void dfs(int i) { in[i] = _timer++; for(int j : adj[i]) { if(j==p[i]) continue; p[j] = i; down[j] = down[i]+1; dfs(j); } out[i] = _timer; } struct segTree { struct node { ll mn; }; int size; vector<node> val; /// minimum, sum count void build(int n) { size = 1; while(size < n) size <<= 1; val = vector<node>(size << 1, {inf}); } void set(int l, int r, ll v, int i, int Lx, int Rx) { if(Rx <= l || Lx >= r) return; if(Lx >= l && Rx <= r) { val[i].mn = min(val[i].mn, v); return; } int m = (Rx+Lx)/2; set(l, r, v, i*2+1, Lx, m); set(l, r, v, i*2+2, m, Rx); } void set(int l, int r, ll v) { set(l, r, v, 0, 0, size); } ll query(int pos, int i, int Lx, int Rx) { if(Rx-Lx==1) return val[i].mn; int m = (Rx+Lx)/2; if(pos<m) return min(val[i].mn, query(pos, i*2+1, Lx, m)); return min(val[i].mn, query(pos, i*2+2, m, Rx)); } ll query(int i) { return query(i, 0, 0, size); } }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, d; cin >> n >> d; for(int i = 2; i <= n; i++) { int x; cin >> x; x++; adj[x].push_back(i); adj[i].push_back(x); } dfs(1); vector<pair<int,int>> v; for(int i = 1; i <= n; i++) v.push_back({down[i], i}); sort(v.begin(), v.end()); reverse(v.begin(), v.end()); segTree tree; tree.build(n); vector<int> ans; for(auto par : v) { int x = par.second; if(tree.query(in[x])+down[x] < d) continue; ans.push_back(x); int h = 0; int H = down[x]; while(x&&h<=d) { tree.set(in[x], out[x], H-2*down[x]); x = p[x]; h++; } } cout << ans.size() << "\n"; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...