Submission #712369

#TimeUsernameProblemLanguageResultExecution timeMemory
712369danikoynovDistributing Candies (IOI21_candies)C++17
100 / 100
1336 ms49632 KiB
#include "candies.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 2e5 + 10; const ll inf = 1e18; int n, q; vector < int > s; ll pref[maxn], cap[maxn]; vector < int > add[maxn], rem[maxn]; struct node { ll max_val, min_val; node(ll _max_val = 0, ll _min_val = 0) { max_val = _max_val; min_val = _min_val; } }; node tree[4 * maxn]; ll lazy[4 * maxn]; void push_lazy(int root, int left, int right) { tree[root].max_val += lazy[root]; tree[root].min_val += lazy[root]; if (left != right) { lazy[root * 2] += lazy[root]; lazy[root * 2 + 1] += lazy[root]; } lazy[root] = 0; } node merge_node(node left, node right) { node cur; cur.max_val = max(left.max_val, right.max_val); cur.min_val = min(left.min_val, right.min_val); return cur; } void update_range(int root, int left, int right, int qleft, int qright, ll val) { push_lazy(root, left, right); if (left > qright || right < qleft) return; if (left >= qleft && right <= qright) { lazy[root] += val; push_lazy(root, left, right); return; } int mid = (left + right) / 2; update_range(root * 2, left, mid, qleft, qright, val); update_range(root * 2 + 1, mid + 1, right, qleft, qright, val); tree[root] = merge_node(tree[root * 2], tree[root * 2 + 1]); } node query(int root, int left, int right, int qleft, int qright) { push_lazy(root, left, right); if (left > qright || right < qleft) return node(-inf, inf); if (left >= qleft && right <= qright) return tree[root]; int mid = (left + right) / 2; return merge_node(query(root * 2, left, mid, qleft, qright), query(root * 2 + 1, mid + 1, right, qleft, qright)); } bool check(int pos, ll val) { node ver = query(1, 0, q + 1, pos, q + 1); ll min_height = ver.min_val; ll max_height = ver.max_val; ///cout << pos << " : " << val << " : " << ver.max_val << " " << ver.min_val << endl; /**for (int i = pos; i < q + 2; i ++) { min_height = min(min_height, pref[i]); max_height = max(max_height, pref[i]); }*/ return (max_height - val > min_height); } vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) { n = c.size(); q = l.size(); s.resize(n, 0); for (int i = 0; i < n; i ++) cap[i] = c[i]; for (int i = 0; i < q; i ++) { add[l[i]].push_back(i); rem[r[i]].push_back(i); } update_range(1, 0, q + 1, 0, q + 1, inf); update_range(1, 0, q + 1, 1, q + 1, -inf); ll fin = 0; for (int i = 0; i < n; i ++) { for (int idx : add[i]) { ///cout << idx << endl; update_range(1, 0, q + 1, idx + 2, q + 1, v[idx]), fin += v[idx]; } /**cout << "check " << i << endl; for (int j = 0; j < q + 2; j ++) cout << query(1, 0, q + 1, j, j).max_val << " "; cout << endl;*/ /**pref[0] = inf; pref[1] = 0; for (int j = 0; j < q; j ++) { pref[j + 2] = pref[j + 1]; if (l[j] <= i && r[j] >= i) { ///cout << "here" << endl; pref[j + 2] += v[j]; } }*/ /**for (int j = 0; j < q + 2; j ++) cout << pref[j] << " "; cout << endl;*/ int lf = 1, rf = q + 1; while(lf <= rf) { int mf = (lf + rf) / 2; if (check(mf, c[i])) lf = mf + 1; else rf = mf - 1; } node ver = query(1, 0, q + 1, rf, q + 1); ll min_height = ver.min_val; ll max_height = ver.max_val; /**for (int i = pos; i < q + 2; i ++) { min_height = min(min_height, pref[i]); max_height = max(max_height, pref[i]); }*/ //cout << "final " << min_height << " " << max_height << " " << rf << endl; ll base =query(1, 0, q + 1, rf, rf).max_val; //cout << base << " " << fin << " " << max_height << endl; if (max_height == query(1, 0, q + 1, rf, rf).max_val) s[i] = fin - min_height; else s[i] = fin - (max_height - c[i]);//, cout << "yes" << endl; for (int idx : rem[i]) { ///cout << idx << endl; update_range(1, 0, q + 1, idx + 2, q + 1, -v[idx]), fin -= v[idx]; } } return s; }

Compilation message (stderr)

candies.cpp: In function 'std::vector<int> distribute_candies(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
candies.cpp:171:12: warning: unused variable 'base' [-Wunused-variable]
  171 |         ll base =query(1, 0, q + 1, rf, rf).max_val;
      |            ^~~~
#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...