This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
using ll = long long;
using pl = pair<ll, ll>;
using pi = pair<int, int>;
#define vt vector
#define f first
#define s second
#define pb push_back
#define all(x) x.begin(), x.end()
#define size(x) ((int) (x).size())
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)
#define F0R(i, b) FOR (i, 0, b)
#define endl '\n'
const ll INF = 1e18;
const int inf = 1e9;
template<template<typename> class Container, typename T>
ostream& operator<<(ostream& os, Container<T> o) {
os << "{";
int g = size(o);
for (auto i : o) os << i << ((--g) == 0 ? "" : ", ");
os << "}";
return os;
}
void _print() {
cerr << "\n";
}
template<typename T, typename ...V>
void _print(T t, V... v) {
cerr << t; if (sizeof...(v)) cerr << ", "; _print(v...);
}
#ifdef LOCAL
#define dbg(x...) cerr << #x << " = "; _print(x);
#else
#define dbg(x...)
#define cerr if (0) std::cerr
#endif
/*
removing a ball just deletes its most ancestor ancestor
balls have a fixed "preferred path" at any given state
if a node has a ball in it, then so does its entire subtree
given some tree, there is a fixed priority among active nodes
*/
#ifdef LOCAL
const int sz = 1 << 4;
#else
const int sz = 1 << 17;
#endif
struct LazySeg {
vt<int> seg, lazy;
void init() {
seg.resize(2 * sz, 1);
lazy.resize(2 * sz, -1);
ROF (i, 1, sz) seg[i] = seg[2 * i] + seg[2 * i + 1];
}
void pull(int i) {
seg[i] = seg[2 * i] + seg[2 * i + 1];
}
void push(int i, int l, int r) {
if (lazy[i] == -1) return;
seg[i] = lazy[i] * (r - l + 1);
if (l != r) F0R (j, 2) lazy[2 * i + j] = lazy[i];
lazy[i] = -1;
}
void upd(int lo, int hi, int v, int i = 1, int l = 0, int r = sz - 1) {
push(i, l, r);
if (lo > r || hi < l) return;
if (lo <= l && r <= hi) {
lazy[i] = v;
push(i, l, r);
return;
}
int m = (l + r) / 2;
upd(lo, hi, v, 2 * i, l, m);
upd(lo, hi, v, 2 * i + 1, m + 1, r);
pull(i);
}
int query(int lo, int hi, int i = 1, int l = 0, int r = sz - 1) {
push(i, l, r);
if (lo > r || hi < l) return 0;
if (lo <= l && r <= hi) return seg[i];
int m = (l + r) / 2;
return query(lo, hi, 2 * i, l, m) + query(lo, hi, 2 * i + 1, m + 1, r);
}
int walk(int k, int i = 1, int l = 0, int r = sz - 1) {
if (l == r) return l;
int m = (l + r) / 2;
push(2 * i, l, m), push(2 * i + 1, m + 1, r);
if (seg[2 * i] >= k) return walk(k, 2 * i, l, m);
else return walk(k - seg[2 * i], 2 * i + 1, m + 1, r);
}
};
int n, q, t;
vt<int> adj[100005];
vt<int> depth, pri, rpri, jmp, par, mn;
LazySeg seg;
int dp(int u) {
int res = u;
for (int v : adj[u]) {
res = min(res, dp(v));
}
return mn[u] = res;
}
void dfs(int u, int p = -1) {
par[u] = p;
for (int v : adj[u]) {
depth[v] = depth[u] + 1;
if (depth[u] + depth[jmp[jmp[u]]] == 2 * depth[jmp[u]]) jmp[v] = jmp[jmp[u]];
else jmp[v] = u;
dfs(v, u);
}
rpri[t] = u;
pri[u] = t++;
}
int lift(int u) {
auto good = [&] (int v) {
return seg.query(pri[v], pri[v]) == 0;
};
while (par[u] != u && good(par[u])) {
if (good(jmp[u])) u = jmp[u];
else u = par[u];
}
return u;
}
main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n >> q;
depth = pri = rpri = jmp = par = mn = vt<int>(n);
int rt = -1;
F0R (i, n) {
int p; cin >> p;
p--;
if (p >= 0) {
par[i] = p;
adj[p].pb(i);
} else {
rt = i;
}
}
seg.init();
dp(rt);
F0R (i, n) sort(all(adj[i]), [&] (int u, int v) { return mn[u] < mn[v]; });
dfs(rt, rt);
F0R (i, q) {
int t, u; cin >> t >> u;
if (t == 1) { // insert balls
int r = seg.walk(u);
seg.upd(0, r, 0);
cout << rpri[r] + 1 << endl;
} else if (t == 2) {
u--;
int v = lift(u);
seg.upd(pri[v], pri[v], 1);
cout << depth[u] - depth[v] << endl;
} else assert(0);
}
}
Compilation message (stderr)
ballmachine.cpp:148:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
148 | main() {
| ^~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |