Submission #102840

#TimeUsernameProblemLanguageResultExecution timeMemory
102840wxh010910Holiday (IOI14_holiday)C++17
100 / 100
1359 ms9340 KiB
#include <bits/stdc++.h> #include "holiday.h" using namespace std; class node { public: node* p; node* l; node* r; int sz; int key; int self; long long sum; node(int key, int self): key(key), self(self) { p = l = r = NULL; sum = self; sz = 1; } void pull() { sz = 1; sum = self; if (l != NULL) { l->p = this; sz += l->sz; sum += l->sum; } if (r != NULL) { r->p = this; sz += r->sz; sum += r->sum; } } }; bool is_bst_root(node* v) { if (v == NULL) { return false; } return (v->p == NULL || (v->p->l != v && v->p->r != v)); } void rotate(node* v) { node* u = v->p; v->p = u->p; if (v->p != NULL) { if (v->p->l == u) { v->p->l = v; } if (v->p->r == u) { v->p->r = v; } } if (v == u->l) { u->l = v->r; v->r = u; } else { u->r = v->l; v->l = u; } u->pull(); v->pull(); } void splay(node* v) { if (v == NULL) { return; } while (!is_bst_root(v)) { node* u = v->p; if (!is_bst_root(u)) { if ((u->l == v) ^ (u->p->l == u)) { rotate(v); } else { rotate(u); } } rotate(v); } } node* insert(node* v, node* u) { u->l = u->r = NULL; while (true) { ++v->sz; v->sum += u->self; if (u->key > v->key) { if (v->r == NULL) { v->r = u; u->p = v; splay(u); return u; } else { v = v->r; } } else { if (v->l == NULL) { v->l = u; u->p = v; splay(u); return u; } else { v = v->l; } } } } node* get_rightmost(node* v) { while (v->r != NULL) { v = v->r; } splay(v); return v; } node* erase(node* v, int key) { while (true) { if (v->key == key) { break; } else if (key > v->key) { v = v->r; } else { v = v->l; } } splay(v); node* l = v->l; node* r = v->r; v->l = v->r = NULL; if (l != NULL) { l->p = NULL; } if (r != NULL) { r->p = NULL; } if (l == NULL) { return r; } if (r == NULL) { return l; } l = get_rightmost(l); l->r = r; l->pull(); return l; } long long query(node* &v, int k) { long long ans = 0; while (true) { if (v->r != NULL) { if (v->r->sz >= k) { v = v->r; continue; } else { k -= v->r->sz; ans += v->r->sum; } } ans += v->self; if (!--k) { splay(v); return ans; } v = v->l; } } long long findMaxAttraction(int n, int start, int d, int attraction[]) { vector<int> order(n); for (int i = 0; i < n; ++i) { order[i] = i; } sort(order.begin(), order.end(), [&](int a, int b) { return attraction[a] < attraction[b]; }); vector<int> pos_in_order(n); for (int i = 0; i < n; ++i) { pos_in_order[order[i]] = i; } vector<node*> tree(n); for (int i = 0; i < n; ++i) { tree[i] = new node(pos_in_order[i], attraction[i]); } node* root = tree[start]; int pl = start, pr = start; long long ans = 0; auto extend = [&](int l, int r) { while (pr < r) { root = insert(root, tree[++pr]); } while (pl > l) { root = insert(root, tree[--pl]); } while (pr > r) { root = erase(root, pos_in_order[pr--]); } while (pl < l) { root = erase(root, pos_in_order[pl++]); } }; function<void(int, int, int, int)> solve = [&](int l, int r, int ll, int rr) { if (l > r) { return; } int mid = (l + r) >> 1, pos = -1; long long best = -1; for (int i = ll; i <= rr; ++i) { int cnt = d - (i - mid) - min(i - start, start - mid); if (cnt <= 0) { break; } extend(mid, i); long long value = root->sz <= cnt ? root->sum : query(root, cnt); if (best < value) { best = value; pos = i; } } ans = max(ans, best); solve(l, mid - 1, ll, pos); solve(mid + 1, r, pos, rr); }; solve(max(0, start - d + 1), start, start, min(n - 1, start + d - 1)); return ans; }

Compilation message (stderr)

grader.cpp: In function 'int main()':
grader.cpp:7:12: warning: variable 'n_s' set but not used [-Wunused-but-set-variable]
     int i, n_s;
            ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...