Submission #465767

#TimeUsernameProblemLanguageResultExecution timeMemory
465767alexxela12345Distributing Candies (IOI21_candies)C++17
3 / 100
1079 ms36404 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; int sum; int max_suf; int min_suf; node(int x, int val) : x(x), val(val) { l = r = NULL; y = rd(); sz = 1; sum = val; max_suf = max(0, val); min_suf = min(0, val); } }; int get_sz(node *n) { return (n == NULL) ? 0 : n->sz; } int get_sum(node *n) { return (n == NULL) ? 0 : n->sum; } int get_max_suf(node *n) { return (n == NULL) ? 0 : n->max_suf; } int get_min_suf(node *n) { return (n == NULL) ? 0 : n->min_suf; } 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); n->sum = n->val + get_sum(n->l) + get_sum(n->r); n->min_suf = min(get_min_suf(n->r), get_sum(n->r) + n->val + get_min_suf(n->l)); n->max_suf = max(get_max_suf(n->r), get_sum(n->r) + n->val + get_max_suf(n->l)); } 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(node *n, int mx_diff, int mx, int mn, int cur) { if (n == NULL) { return 0; } int mx1 = max(max(mx, get_sum(n->r) + n->val + cur), get_max_suf(n->r) + cur); int mn1 = min(min(mn, get_sum(n->r) + n->val + cur), get_min_suf(n->r) + cur); if (mx1 - mn1 > mx_diff) { return get_fst_diff(n->r, mx_diff, mx, mn, cur) + 1 + get_sz(n->l); } return get_fst_diff(n->l, mx_diff, mx1, mn1, cur + get_sum(n->r) + n->val); } 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 ans = get_fst_diff(mda.root, mx_diff, 0, 0, 0); return ans; 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) { assert(ans == i + 1); return i + 1; } } assert(ans == 0); return 0; } int get_min_suf(mdata &mda, int fst) { auto pp = split_sz(mda.root, fst); int ans = get_min_suf(pp.second); mda.root = merge(pp.first, pp.second); return ans; 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) { auto pp = split_sz(mda.root, fst); int ans = get_max_suf(pp.second); mda.root = merge(pp.first, pp.second); return ans; 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...