Submission #1302203

#TimeUsernameProblemLanguageResultExecution timeMemory
1302203SkillIssueWAGuyObstacles for a Llama (IOI25_obstacles)C++20
100 / 100
749 ms220556 KiB
/* * * ┏┓ ┏┓+ + * ┏┛┻━━━┛┻┓ + + * ┃ ━ ┃ ++ + + + * ████━████+ * ◥██◤ ◥██◤ + * ┃ ┻ ┃ * ┗━┓ ┏━┛ + + * ┃ ┃ + + + +Code is far away from * ┃ ┃ + bug with the llama protecting * ┃ ┗━━━┓ 神兽保佑,代码无bug * ┃ ┣┓ * ┃ ┏┛ * ┗┓┓┏━┳┓┏┛ + + + + * ┃┫┫ ┃┫┫ * ┗┻┛ ┗┻┛+ + + + */ //thanks cindy // should've ac'd in contest #include "obstacles.h" #include<bits/stdc++.h> #define ll long long using namespace std; // T[i] > H[i] means no obstacle, T[i] <= H[i] means obstacle // Note: N is #columns, M is #rows, reversed from problem statement ll N, M, logN = 23; vector<ll> T, H; char *_BRK; void *galloc(ll sz) { auto out = (void *)_BRK; _BRK += sz; return out; } struct plist { ll v; plist *r; plist (ll gay) { v = gay; r = nullptr; } }; struct pvec { plist *l, *r; pvec (){ l = r = nullptr; } }; struct snode { ll l, r, vi, va; snode *lc, *rc; void construct(vector<ll> &gay) { if (l == r) { vi = va = gay[l]; return; } lc = (snode*)(malloc(sizeof(snode))); rc = (snode*)(malloc(sizeof(snode))); lc -> l = l; rc -> r = r; lc -> r = floor((l+r)/2.0); rc -> l = lc -> r + 1; lc -> construct(gay); rc -> construct(gay); vi = min(lc -> vi, rc -> vi); va = max(lc -> va, rc -> va); } ll qmin(ll li, ll ri){ if (li == l && ri == r) return vi; ll output = 1e18; if (li <= lc -> r) output = lc -> qmin(li, min(ri, lc -> r)); if (ri >= rc -> l) output = min(output, rc -> qmin(max(li, rc -> l), ri)); return output; } ll qmax(ll li, ll ri){ if (li == l && ri == r) return va; ll output = -1e18; if (li <= lc -> r) output = lc -> qmax(li, min(ri, lc -> r)); if (ri >= rc -> l) output = max(output, rc -> qmax(max(li, rc -> l), ri)); return output; } pvec* qhum(ll li, ll ri, ll val){ // returns a sorted linked list on postions >= val pvec *out; out = (pvec*)(malloc(sizeof(pvec))); if (va < val) { out -> l = out -> r = nullptr; return out; } if (l == r) { out -> l = out -> r = (plist*)(malloc(sizeof(plist))); out -> l -> v = li; out -> r -> r = nullptr; return out; } if (li <= lc -> r) { free(out); out = lc -> qhum(li, min(lc -> r, ri), val); if (ri >= rc -> l){ if (out -> l == nullptr) { free(out); return rc -> qhum(max(li, rc -> l), ri, val); } auto p = rc -> qhum(max(li, rc -> l), ri, val); if (p -> l != nullptr) out -> r -> r = p -> l; if (p -> l != nullptr) out -> r = p -> r; free(p); } return out; } else { free(out); return rc -> qhum(li, ri, val); } } ll qtemp(ll li, ll ri, ll val) { // find the first position > val, or return -69 if (l == r) { if (va <= val) return -69; else return l; } if (va <= val) return -69; ll output = -69; if (li <= lc -> r) output = lc -> qtemp(li, min(ri, lc -> r), val); if (output == -69){ if (ri >= rc -> l) output = rc -> qtemp(max(li, rc -> l), ri, val); } return output; } ll qhl(ll li, ll ri, ll val) { // find the first position < val, or return -69 if (l == r) { if (vi >= val) return -69; else return l; } if (vi >= val) return -69; ll output = -69; if (li <= lc -> r) output = lc -> qhl(li, min(ri, lc -> r), val); if (output == -69){ if (ri >= rc -> l) output = rc -> qhl(max(li, rc -> l), ri, val); } return output; } ll qhr(ll li, ll ri, ll val) { // find the last position < val, or return -69 if (l == r) { if (vi >= val) return -69; else return l; } if (vi >= val) return -69; ll output = -69; if (ri >= rc -> l) output = rc -> qhr(max(li, rc -> l), ri, val); if (output == -69){ if (li <= lc -> r) output = lc -> qhr(li, min(ri, lc -> r), val); } return output; } }; snode rootn, rootm; class tnode; struct Lca { // To pass, left <= l, right >= r tnode *pos; ll l, r; Lca(){} Lca (Lca a, Lca b){ // Combines ancestor to descendent l = min(a.l, b.l); r = max(a.r, b.r); pos = a.pos; } Lca (tnode *a, ll b, ll c){ // Make a boring object lol pos = a; l = b; r = c; } }; ll adjust (ll a, ll b) { if (a == -69) return b; return a; } struct tnode{ ll l, r,h, th, pl, pr; // l, r for range, h for y value, th for tree height, //pl pr for Lca object parent pointer vector<tnode*> ch; // list of children pointers vector<Lca> lca; // LCA construct tnode *par; // parent pointer void build (vector<tnode*> &Lea, bool _indicator = true) { // do the LCA shit here ch = vector<tnode*>(0); if ( l==53701 || l == 105895) { int asdfas = 0; asdfas ++; } if (_indicator) { lca = vector<Lca>(0); lca = vector<Lca> (logN); lca[0] = Lca(par, pl, pr); for (ll i = 1; i < logN; i++) { lca[i] = Lca(lca[i-1].pos -> lca[i-1], lca[i-1]); } } if (h == 0) { for (ll i = l; i <= r; i++) Lea[i] = this; return; } ll Ta = rootm.qmax(0, h-1); pvec *X = rootn.qhum(l, r, Ta); plist *lll, *rrr; lll = (plist*)(malloc(sizeof(plist))); rrr = (plist*)(malloc(sizeof(plist))); *lll = plist(l-1); *rrr = plist(r + 1); lll -> r = X -> l; X -> l = lll; if (X -> r == nullptr) X -> r = lll; X -> r -> r = rrr; X -> r = rrr; for (plist *i = X -> l; i -> r != nullptr; i = i -> r){ if (i -> r -> v - i -> v <= 1) continue; ch.push_back((tnode*)(galloc(sizeof(tnode)))); ch.back() -> l = i -> v + 1; ch.back() -> r = i -> r -> v - 1; ch.back() -> th = th + 1; ch.back() -> par = this; // now find height, pl, pr ll pe = rootn.qmax(ch.back() -> l, ch.back() -> r); ch.back() -> h = rootm.qtemp(0, h - 1, pe); pe = rootm.qmin(ch.back() -> h, h - 1); if (_indicator){ ch.back() -> pl = rootn.qhr(ch.back() -> l, ch.back() -> r, pe); ch.back() -> pr = adjust(rootn.qhl(ch.back() -> l, ch.back() -> r, pe), N+M+5); } else { ch.back() -> pl = -69; ch.back() -> pr = N+M+5; } ch.back() -> build(Lea); } } }; Lca trace(tnode *a, tnode *b){ if (a -> th < b -> th) { auto c = a; a = b; b = c; } Lca A(a, N+1, -1), B(b, N+1, -1); for (ll i = logN-1; i >= 0; i--){ if (a -> lca[i].pos -> th >= b -> th){ A = Lca(a -> lca[i], A); a = A.pos; } } if (a != b) { for (ll i = logN-1; i >= 0; i--){ if (a -> lca[i].pos != b -> lca[i].pos){ A = Lca(a -> lca[i], A); a = A.pos; B = Lca(b -> lca[i], B); b = B.pos; } } A = Lca(a -> lca[0], A); a = A.pos; B = Lca(b -> lca[0], B); b = B.pos; } A = Lca(A, B); return A; } vector<tnode*> Leaf; tnode gayroot; void initialize(std::vector<int> t, std::vector<int> h) { _BRK = (char*)malloc(sizeof(tnode) * 1e6); N = h.size(); M = t.size(); T = vector<ll>(M); H = vector<ll>(N); Leaf = vector<tnode*> (N, nullptr); for (ll i = 0; i < N; i++) H[i] = h[i]; for (ll i = 0; i < M; i++) T[i] = t[i]; rootn.l = rootm.l = 0; rootn.r = N-1; rootm.r = M-1; rootn.construct(H); rootm.construct(T); gayroot.l = 0; gayroot.r = N-1; gayroot.lca = vector<Lca>(logN, Lca(&gayroot, N+1, -1)); gayroot.pl = -1; gayroot.pr = N; gayroot.h = M; gayroot.th = 0; gayroot.build(Leaf, false); return; } bool can_reach(int L, int R, int S, int D) { ll l = L, r = R, a = S, b = D; if (Leaf[a] == nullptr || Leaf[b] == nullptr) return false; //return Leaf[a] == Leaf[b]; auto P = trace(Leaf[a], Leaf[b]); return (l <= P.l) && (r >= P.r); }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...