Submission #1289035

#TimeUsernameProblemLanguageResultExecution timeMemory
1289035g4yuhgBall Machine (BOI13_ballmachine)C++20
100 / 100
651 ms43520 KiB
#include<bits/stdc++.h> typedef long long ll; #define pii pair<ll, ll> #define fi first #define se second #define endl '\n' #define TASK "+" #define N 100005 #define LOG 16 using namespace std; const ll offset = 1e6, inf = 1e18; bool ghuy4g; struct Node { ll sum, mn; } st[4 * N], f[4 * N]; ll n, q, in[N], out[N], par[N][LOG + 2], timeDfs, dep[N], tour[N], root, sz[N]; vector<ll> adj[N]; bool is[N]; ll mini[N]; bool cmp(ll u, ll v) { return mini[u] < mini[v]; } void dfs1(ll u, ll parent) { mini[u] = u; for (auto v : adj[u]) { if (v == parent) continue; dfs1(v, u); mini[u] = min(mini[u], mini[v]); } } void dfs(ll u, ll parent) { in[u] = ++ timeDfs; sz[u] = 1; tour[timeDfs] = u; for (auto v : adj[u]) { if (v == parent) continue; dep[v] = dep[u] + 1; par[v][0] = u; dfs(v, u); sz[u] += sz[v]; } if (adj[u].size() == 1 && u != root) is[u] = 1; out[u] = timeDfs; } Node cb(Node A, Node B) { Node res; res.sum = A.sum + B.sum; res.mn = min(A.mn, B.mn); return res; } void build(ll id, ll l, ll r) { if (l == r) { st[id] = {1, inf}; if (is[tour[l]]) { st[id] = {1, l}; } f[id] = {-1, -1}; return; } ll mid = (l + r) / 2; build(id * 2, l, mid); build(id * 2 + 1, mid + 1, r); st[id] = cb(st[id * 2], st[id * 2 + 1]); f[id] = {-1, -1}; } void pre() { dfs1(root, root); for (int i = 1; i <= n; i ++) { sort(adj[i].begin(), adj[i].end(), cmp); } dfs(root, root); for (int j = 1; j <= LOG; j ++) { for (int i = 1; i <= n; i ++) { ll p = par[i][j - 1]; par[i][j] = par[p][j - 1]; } } build(1, 1, n); } ll kth_par(ll u, ll k) { for (int j = LOG; j >= 0; j --) { if (k >= (1 << j)) { k -= (1 << j); u = par[u][j]; } } return u; } void lazy(ll id) { if (f[id].sum == -1) return; st[id] = f[id]; if (id * 2 < 4 * N) f[id * 2] = f[id]; if (id * 2 + 1 < 4 * N) f[id * 2 + 1] = f[id]; f[id] = {-1, -1}; } Node get(ll id, ll l, ll r, ll L, ll R) { lazy(id); if (l > R || r < L) return {0LL, inf}; if (L <= l && r <= R) return st[id]; ll mid = (l + r) / 2; return cb(get(id * 2, l, mid, L, R), get(id * 2 + 1, mid + 1, r, L, R)); } void update(ll id, ll l, ll r, ll L, ll R, Node v) { lazy(id); if (l > R || r < L) return; if (L <= l && r <= R) { f[id] = v; lazy(id); return; } ll mid = (l + r) / 2; update(id * 2, l, mid, L, R, v); update(id * 2 + 1, mid + 1, r, L, R, v); st[id] = cb(st[id * 2], st[id * 2 + 1]); } void solve1(ll k) { // add k con vao ll node = tour[st[1].mn]; // dinh u, dinh thap nhat //cout << "bdnode " << node << endl; //return; ll kq = 0; while (k) { node = tour[st[1].mn]; ll l = 0, r = dep[node], ans = 0, ans_u = node; Node res; ll l2 = 0; while (l <= r) { ll mid = (l + r) / 2; // nhay len mid con ll u = kth_par(node, mid); Node xet = get(1, 1, n, in[u], out[u]); //cout << " mid " << mid << " u " << u << " " << xet.sum << " l r " << l << " " << r << endl; //if (l2 >= 3) break; if (xet.sum <= k) { ans = mid; ans_u = u; res = xet; l = mid + 1; } else { r = mid - 1; } } //cout << " ans_u " << ans_u << " " << res.sum << endl; // o node u bi mat het, k -= size kq = ans_u; k -= res.sum; update(1, 1, n, in[ans_u], out[ans_u], {0, inf}); ll p = par[ans_u][0]; if (p) { Node xet = get(1, 1, n, in[p], out[p]); if (xet.sum == 1) { update(1, 1, n, in[p], in[p], {xet.sum, in[p]}); // thanh la } } if (st[1].mn < inf) { node = tour[st[1].mn]; } } cout << kq << endl; } void solve2(ll x) { // rut bong o x, ban dau dinh hld, nhung co nxet: ko co chuyen o par[x][j] co, ma o par[x][j + 2] cung co if (get(1, 1, n, in[x], in[x]).sum == 1) { cout << -1 << endl; return; } ll l = 0, r = dep[x], ans = -1, ans_u = -1; while (l <= r) { ll mid = (l + r) / 2; ll u = kth_par(x, mid); Node xet = get(1, 1, n, in[u], in[u]); if (xet.sum == 0) { ans = mid; ans_u = u; l = mid + 1; } else if (xet.sum == 1) { r = mid - 1; } else { cout << "ngu"; exit(4); } } if (ans_u == -1) { cout << "ngu2"; exit(5); } update(1, 1, n, in[ans_u], in[ans_u], {1, in[ans_u]}); // o u mat bong is[ans_u] = 1; // chac chan bien thanh la if (par[ans_u][0]) { ll p = par[ans_u][0]; Node xet = get(1, 1, n, in[p], in[p]); if (xet.mn == in[p]) { update(1, 1, n, in[p], in[p], {xet.sum, inf}); // vi ko con la la is[p] = 0; } } cout << abs(dep[ans_u] - dep[x]) << endl; } void solve() { for (int id = 1; id <= q; id ++) { ll type, x; cin >> type >> x; if (type == 1) { solve1(x); } else { solve2(x); } } } bool klinh; signed main() { // freopen("test.inp", "r", stdin); //freopen("test.out", "w", stdout); //srand(time(0)); ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> q; for (int i = 1; i <= n; i ++) { ll p; cin >> p; if (p == 0) { root = i; } else { adj[i].push_back(p); adj[p].push_back(i); //cout << i << " " << p << endl; } } pre(); solve(); cerr << fabs(&klinh - &ghuy4g) / double(1024 * 1024); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...