Submission #465753

#TimeUsernameProblemLanguageResultExecution timeMemory
465753alexxela12345Distributing Candies (IOI21_candies)C++17
3 / 100
5094 ms26380 KiB
#include "candies.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; mt19937 rd(179); struct node { node *l, *r; int x, y; int val; int sz; node(int x, int val) : x(x), val(val) { l = r = NULL; y = rd(); sz = 1; } }; int get_sz(node *n) { return (n == NULL) ? 0 : n->sz; } int get_ct(node *n, int i) { if (i == get_sz(n->l)) { return n->val; } if (i < get_sz(n->l)) { return get_ct(n->l, i); } return get_ct(n->r, i - get_sz(n->l) - 1); } int getInd(node *n, int x) { if (n == NULL) return 0; if (x < n->x) return getInd(n->l, x); if (x == n->x) return get_sz(n->l); return getInd(n->r, x) + get_sz(n->l) + 1; } void pull(node *n) { n->sz = 1 + get_sz(n->l) + get_sz(n->r); } pair<node *, node *> split_sz(node *n, int k) { if (n == NULL) return {n, n}; if (k <= get_sz(n->l)) { auto pp = split_sz(n->l, k); n->l = pp.second; pull(n); return {pp.first, n}; } auto pp = split_sz(n->r, k - 1 - get_sz(n->l)); n->r = pp.first; pull(n); return {n, pp.second}; } node *merge(node *a, node *b) { if (a == NULL) { return b; } if (b == NULL) return a; if (a->y > b->y) { a->r = merge(a->r, b); pull(a); return a; } b->l = merge(a, b->l); pull(b); return b; } struct mdata { node *root = NULL; int size(); int get(int); }; int mdata::size() { return get_sz(root); } int mdata::get(int i) { return get_ct(root, i); } void erase(mdata &mda, int i, int x) { int ind = getInd(mda.root, i); auto pp1 = split_sz(mda.root, ind); auto pp2 = split_sz(pp1.second, 1); mda.root = merge(pp1.first, pp2.second); } void add(mdata &mda, int i, int x) { int ind = getInd(mda.root, i); auto pp = split_sz(mda.root, ind); mda.root = merge(merge(pp.first, new node(i, x)), pp.second); } int get_fst_diff(mdata &mda, int mx_diff) { // returns index to first arrow after which everything contains in a segment of size mx int cur = 0; int mn = 0, mx = 0; for (int i = mda.size() - 1; i >= 0; i--) { int a = mda.get(i); cur += a; mn = min(mn, cur); mx = max(mx, cur); if (mx - mn >= mx_diff) { return i + 1; } } return 0; } int get_min_suf(mdata &mda, int fst) { int cur = 0; int mn = 0; for (int i = mda.size() - 1; i >= fst; i--) { cur += mda.get(i); if (cur < mn) { mn = cur; } } return mn; } int get_max_suf(mdata &mda, int fst) { int cur = 0; int mn = 0; for (int i = mda.size() - 1; i >= fst; i--) { cur += mda.get(i); if (cur > mn) { mn = cur; } } return mn; } int get_ans(mdata &mda, int mx) { int fst = get_fst_diff(mda, mx); int start = 0; if (fst == 0) { start = 0; } else { int a = mda.get(fst - 1); if (a > 0) { start = mx; } else { start = 0; } } if (start == 0) { int ans = get_max_suf(mda, fst); return start + ans; } else { int ans = get_min_suf(mda, fst); return start + ans; } } vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) { int n = c.size(); vector<vector<int>> add_evs(n + 1), rem_evs(n + 1); for (int i = 0; i < (int) l.size(); i++) { add_evs[l[i]].push_back(i); rem_evs[r[i] + 1].push_back(i); } mdata mda; vector<int> ans; ans.reserve(n); for (int i = 0; i < n; i++) { for (int el : rem_evs[i]) { erase(mda, el, v[el]); } for (int el : add_evs[i]) { add(mda, el, v[el]); } ans.push_back(get_ans(mda, c[i])); } return ans; }
#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...