제출 #1129235

#제출 시각아이디문제언어결과실행 시간메모리
1129235GervidRabbit Carrot (LMIO19_triusis)C++20
0 / 100
4 ms840 KiB
#include <iostream> #include <vector> #include <set> #include <limits.h> #include <random> #include <array> using namespace std; mt19937 r; struct Treap { int prio, dpdata, height, size, dpmin; array<Treap*, 2> kids; Treap(int _dpdata, int _height) { height = _height; dpdata = _dpdata; prio = r(); size = 1; dpmin = dpdata; kids = { NULL, NULL }; } }; int getsize(Treap* treap) { return treap != NULL ? treap->size : 0; } int getdpmin(Treap* treap) { return treap != NULL ? treap->dpmin : INT_MAX; } void recalc(Treap* me) { me->dpmin = min(me->dpdata, min(getdpmin(me->kids[0]), getdpmin(me->kids[1]))); me->size = 1 + getsize(me->kids[0]) + getsize(me->kids[1]); } array<Treap*, 2> split(Treap* me, int x) { if (me == NULL) return { NULL, NULL }; if (x <= getsize(me->kids[0])) { array<Treap*, 2> res = split(me->kids[0], x); me->kids[0] = res[1]; recalc(me); return { res[0], me }; } else { array<Treap*, 2>res = split(me->kids[1], x - getsize(me->kids[0]) - 1); me->kids[1] = res[0]; recalc(me); return { me, res[1] }; } } Treap* merge(Treap* left, Treap* right) { if (left == NULL) return right; if (right == NULL) return left; if (left->prio < right->prio) { left->kids[1] = merge(left->kids[1], right); recalc(left); return left; } else { right->kids[0] = merge(left, right->kids[0]); recalc(right); return right; } } int findidx(int x, Treap* treap, int index = -1) { if (index == -1) index = getsize(treap->kids[0]); if (treap->height == x && (treap->kids[1] == NULL || treap->kids[1]->height != x)) return index; if (treap->height <= x) { if (treap->kids[1] == NULL) return index; return findidx(x, treap->kids[1], index + getsize(treap->kids[1]->kids[0]) + 1); } else { if (treap->kids[0] == NULL) return index; return findidx(x, treap->kids[0], index - getsize(treap->kids[0]->kids[1]) - 1); } } int main() { iostream::sync_with_stdio(0); cin.tie(0); int n, m, i; cin >> n >> m; vector<int> a(n+1); for (i = 1; i <= n; i++) cin >> a[i]; a[0] = 0; vector<Treap> storage = { Treap(n+1, -1) }; //dp value is always offset by i storage.reserve(n+2); Treap* treap = &storage[storage.size()-1]; multiset<int> heights = { -1 }; int dis = 0, dpmin = 0, index, smaller_height; for (i = n; i >= 0; i--) { set<int>::iterator it = prev(heights.upper_bound(a[i] + dis)); smaller_height = *it; index = findidx(smaller_height, treap); array<Treap*, 2> parts = split(treap, index+1); dpmin = parts[0]->dpmin - i - 1; storage.push_back(Treap(dpmin + i, a[i] + dis)); treap = merge(parts[0], merge(&storage[storage.size()-1], parts[1])); heights.insert(a[i] + dis); dis += m; } cout << dpmin; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...