Submission #1214778

#TimeUsernameProblemLanguageResultExecution timeMemory
1214778anonymous321The Potion of Great Power (CEOI20_potion)C++20
38 / 100
1507 ms327680 KiB
#include <bits/stdc++.h> using namespace std; struct node { short val = 0; //int nextl = -1; int nextr = -1; int l = -1, r = -1; }; struct st { vector<node> v; int as; }; st build (int n) { int as = 1 << (__lg(n) + 1); vector<node> v (as*2); for (int i = as-1; i > 0; i--) { v[i].l = i*2; v[i].r = i*2 + 1; } return {v, as}; } pair<int, int> update (st &seg, int id, int d, int i, int lo = 0, int hi = -1) { if (hi == -1) hi = seg.as; int nid = seg.v.size(); seg.v.push_back(seg.v[i]); if (lo == hi-1) { seg.v[nid].val += d; return {nid, nid}; } int mid = (lo + hi) / 2; int qa, qb; if (id < mid) { tie(qa, qb) = update(seg, id, d, seg.v[nid].l, lo, mid); seg.v[nid].l = qa; } else { tie(qa, qb) = update(seg, id, d, seg.v[nid].r, mid, hi); seg.v[nid].r = qa; } seg.v[nid].val = seg.v[seg.v[nid].l].val + seg.v[seg.v[nid].r].val; return {nid, qb}; } int query (st &seg, int id, int i, int lo = 0, int hi = -1) { if (hi == -1) hi = seg.as; if (lo == hi-1) return i; int mid = (lo + hi) / 2; if (id < mid) { return query(seg, id, seg.v[i].l, lo, mid); } else { return query(seg, id, seg.v[i].r, mid, hi); } } int searchl (st &seg, int id, int i, int lo = 0, int hi = -1) { if (hi == -1) hi = seg.as; if (lo >= id) return -1; if (lo == hi-1) { if (seg.v[i].val > 0) return lo; else return -1; } int mid = (lo + hi) / 2; int lid = seg.v[i].l; int rid = seg.v[i].r; int sol = -1; if (seg.v[rid].val > 0) { sol = searchl(seg, id, rid, mid, hi); } if (sol == -1 && seg.v[lid].val > 0) { sol = searchl(seg, id, lid, lo, mid); } return sol; } int searchr (st &seg, int id, int i, int lo = 0, int hi = -1) { if (hi == -1) hi = seg.as; if (hi <= id+1) return -1; if (lo == hi-1) { if (seg.v[i].val > 0) return lo; else return -1; } int mid = (lo + hi) / 2; int lid = seg.v[i].l; int rid = seg.v[i].r; int sol = -1; if (seg.v[lid].val > 0) { sol = searchr(seg, id, lid, lo, mid); } if (sol == -1 && seg.v[rid].val > 0) { sol = searchr(seg, id, rid, mid, hi); } return sol; } int n, d; //vector<int> vh; vector<int> vhs; vector<int> vid; st seg; vector<vector<pair<int, int>>> vroot; // day - root int add_friend (int a, int b) { int root = vroot[a].back().second; int l = searchl(seg, b+1, root); int r = searchr(seg, b+1, root); int nl, nr, ni; tie(root, nl) = update(seg, l, 0, root); tie(root, nr) = update(seg, r, 0, root); tie(root, ni) = update(seg, b+1, 1, root); seg.v[nl].nextr = b+1; /*seg.v[nr].nextl = b+1; seg.v[ni].nextl = l;*/ seg.v[ni].nextr = r; return root; } int rem_friend (int a, int b) { int root = vroot[a].back().second; int l = searchl(seg, b+1, root); int r = searchr(seg, b+1, root); int nl, nr, ni; tie(root, nl) = update(seg, l, 0, root); tie(root, nr) = update(seg, r, 0, root); tie(root, ni) = update(seg, b+1, -1, root); seg.v[nl].nextr = r; //seg.v[nr].nextl = l; return root; } void init(int N, int D, int H[]) { n = N; d = D; vhs = vector<int> (N); vector<pair<int, int>> vq; for (int i = 0; i < N; i++) { vhs[i] = H[i]; vq.push_back({vhs[i], i}); } sort(vhs.begin(), vhs.end()); sort(vq.begin(), vq.end()); vid = vector<int> (n); for (int i = 0; i < N; i++) { vid[vq[i].second] = i; } seg = build(n+2); int root = 1; int l, r; tie(root, l) = update(seg, 0, 1, 1); tie(root, r) = update(seg, n+1, 1, root); seg.v[l].nextr = n+1; //seg.v[r].nextl = 0; vroot = vector<vector<pair<int, int>>> (n, vector<pair<int, int>> {{-1, root}}); } void curseChanges(int U, int A[], int B[]) { for (int i = 0; i < U; i++) { int a = vid[A[i]]; int b = vid[B[i]]; if (seg.v[query(seg, b+1, vroot[a].back().second)].val == 1) { vroot[a].push_back({i, rem_friend(a, b)}); vroot[b].push_back({i, rem_friend(b, a)}); } else { vroot[a].push_back({i, add_friend(a, b)}); vroot[b].push_back({i, add_friend(b, a)}); } } } int question(int x, int y, int v) { int x1 = vid[x]; int y1 = vid[y]; int rootx = (--upper_bound(vroot[x1].begin(), vroot[x1].end(), make_pair(v, 0)))->second; int rooty = (--upper_bound(vroot[y1].begin(), vroot[y1].end(), make_pair(v, 0)))->second; int l = query(seg, 0, rootx); int r = query(seg, 0, rooty); int sol = 1e9; int curl = 0; int curr = 0; while (seg.v[l].nextr != -1) { curl = seg.v[l].nextr; l = query(seg, seg.v[l].nextr, rootx); if (seg.v[l].nextr == -1) continue; while (seg.v[r].nextr != -1 && seg.v[r].nextr <= curl) { curr = seg.v[r].nextr; r = query(seg, seg.v[r].nextr, rooty); } if (curr != 0 && curr != n+1) { int nsol = vhs[curl-1] - vhs[curr - 1]; sol = min(sol, nsol); } if (seg.v[r].nextr != -1 && seg.v[r].nextr != 0 && seg.v[r].nextr != n+1) { int nsol = abs(vhs[curl-1] - vhs[seg.v[r].nextr - 1]); sol = min(sol, nsol); } } return sol; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...