제출 #463824

#제출 시각아이디문제언어결과실행 시간메모리
463824JovanBBall Machine (BOI13_ballmachine)C++17
100 / 100
362 ms24596 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using ld = long double; const int N = 100000; const int LOG = 18; int par[N+5][LOG+1]; int mnn[N+5]; vector <int> graf[N+5]; void dfs_calc(int v){ mnn[v] = v; for(int j=1; j<=LOG; j++) par[v][j] = par[par[v][j-1]][j-1]; for(auto c : graf[v]){ dfs_calc(c); mnn[v] = min(mnn[v], mnn[c]); } sort(graf[v].begin(), graf[v].end(), [](int a, int b){ return mnn[a] < mnn[b]; }); } int gde[N+5]; int niz[N+5]; int tjm; void dfs(int v){ for(auto c : graf[v]) dfs(c); ++tjm; niz[tjm] = v; gde[v] = tjm; } struct Segment{ int sum; bool lazy; } seg[4*N+5]; void propagate(int node, int l, int r){ if(!seg[node].lazy) return; seg[node].sum = r-l+1; if(l == r){ seg[node].lazy = 0; return; } seg[node*2].lazy |= seg[node].lazy; seg[node*2+1].lazy |= seg[node].lazy; seg[node].lazy = 0; } void mrg(int node, int l, int r){ int mid = (l+r)/2; propagate(node*2, l, mid); propagate(node*2+1, mid+1, r); seg[node].sum = seg[node*2].sum + seg[node*2+1].sum; } void upd_range(int node, int l, int r, int tl, int tr){ if(tl > r || l > tr) return; if(tl <= l && r <= tr){ seg[node].lazy = 1; propagate(node, l, r); return; } int mid = (l+r)/2; upd_range(node*2, l, mid, tl, tr); upd_range(node*2+1, mid+1, r, tl, tr); mrg(node, l, r); } void upd_point(int node, int l, int r, int x){ propagate(node, l, r); if(l == r){ seg[node].sum = 0; return; } int mid = (l+r)/2; if(x <= mid) upd_point(node*2, l, mid, x); else upd_point(node*2+1, mid+1, r, x); mrg(node, l, r); } int find_first(int node, int l, int r, int k){ if(l == r) return l; int mid = (l+r)/2; propagate(node*2, l, mid); propagate(node*2+1, mid+1, r); if(mid-l+1 - seg[node*2].sum >= k) return find_first(node*2, l, mid, k); return find_first(node*2+1, mid+1, r, k - (mid-l+1 - seg[node*2].sum)); } int get_point(int node, int l, int r, int x){ propagate(node, l, r); if(l == r) return seg[node].sum; int mid = (l+r)/2; if(x <= mid) return get_point(node*2, l, mid, x); return get_point(node*2+1, mid+1, r, x); } int main(){ ios_base::sync_with_stdio(false), cin.tie(0); cout.precision(10); cout << fixed; int n, qrs; cin >> n >> qrs; int root = 0; for(int i=1; i<=n; i++){ cin >> par[i][0]; if(par[i][0] == 0) root = i; else graf[par[i][0]].push_back(i); } dfs_calc(root); dfs(root); while(qrs--){ int typ; cin >> typ; if(typ == 1){ int cnt; cin >> cnt; int k = find_first(1, 1, n, cnt); upd_range(1, 1, n, 1, k); cout << niz[k] << "\n"; } else{ int v; cin >> v; int res = 0; for(int j=LOG; j>=0; j--) if(par[v][j] && get_point(1, 1, n, gde[par[v][j]])) res += (1 << j), v = par[v][j]; cout << res << "\n"; upd_point(1, 1, n, gde[v]); } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...