제출 #815412

#제출 시각아이디문제언어결과실행 시간메모리
815412becaido사탕 분배 (IOI21_candies)C++17
100 / 100
508 ms38076 KiB
#pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx,popcnt,sse4,abm") #include <bits/stdc++.h> using namespace std; #ifndef WAIMAI #include "candies.h" #endif #ifdef WAIMAI #define debug(HEHE...) cout << "[" << #HEHE << "] : ", dout(HEHE) void dout() {cout << '\n';} template<typename T, typename...U> void dout(T t, U...u) {cout << t << (sizeof...(u) ? ", " : ""), dout(u...);} #else #define debug(...) 7122 #endif #define ll long long #define Waimai ios::sync_with_stdio(false), cin.tie(0) #define FOR(x,a,b) for (int x = a, I = b; x <= I; x++) #define pb emplace_back #define F first #define S second #define lpos pos*2 #define rpos pos*2+1 const ll INF = 1e18; const int SIZE = 2e5 + 5; int n, q; vector<pair<int, int>> op[SIZE]; struct Node { ll mn, mx, lazy; Node() = default; Node operator + (const Node& r) const { Node re = Node(); re.mn = min(mn, r.mn); re.mx = max(mx, r.mx); return re; } } node[SIZE * 4]; void push(int pos, int l, int r) { node[pos].mn += node[pos].lazy; node[pos].mx += node[pos].lazy; if (l < r) { node[lpos].lazy += node[pos].lazy; node[rpos].lazy += node[pos].lazy; } node[pos].lazy = 0; } void pull(int pos, int l, int r) { int mid = (l + r) / 2; push(lpos, l, mid); push(rpos, mid + 1, r); node[pos] = node[lpos] + node[rpos]; } void upd(int pos, int l, int r, int L, int R, int x) { if (l == L && r == R) { node[pos].lazy += x; return; } push(pos, L, R); int mid = (L + R) / 2; if (r <= mid) upd(lpos, l, r, L, mid, x); else if (l > mid) upd(rpos, l, r, mid + 1, R, x); else { upd(lpos, l, mid, L, mid, x); upd(rpos, mid + 1, r, mid + 1, R, x); } pull(pos, L, R); } void upd(int p, int x) { upd(1, p, q, 0, q, x); } ll que(int pos, int l, int r, int p) { push(pos, l, r); if (l == r) return node[pos].mn; int mid = (l + r) / 2; if (p <= mid) return que(lpos, l, mid, p); else return que(rpos, mid + 1, r, p); } ll que(int l, int r) { return que(1, 0, q, r) - (l ? que(1, 0, q, l - 1) : 0); } ll que(int pos, int l, int r, int L, int R, int ty) { push(pos, L, R); if (l == L && r == R) return (ty == 0 ? node[pos].mn : node[pos].mx); int mid = (L + R) / 2; if (r <= mid) return que(lpos, l, r, L, mid, ty); if (l > mid) return que(rpos, l, r, mid + 1, R, ty); ll lval = que(lpos, l, mid, L, mid, ty); ll rval = que(rpos, mid + 1, r, mid + 1, R, ty); return ty == 0 ? min(lval, rval) : max(lval, rval); } int sch_mn(int pos, int l, int r) { if (l == r) return l; int mid = (l + r) / 2; push(pos, l, r); push(rpos, mid + 1, r); if (node[rpos].mn == node[pos].mn) return sch_mn(rpos, mid + 1, r); else return sch_mn(lpos, l, mid); } int sch_mn() { return sch_mn(1, 0, q); } tuple<int, ll, ll> sch_rdif(int pos, int l, int r, int lim, ll pmn = INF, ll pmx = -INF) { push(pos, l, r); if (l == r) { pmn = min(pmn, node[pos].mn); pmx = max(pmx, node[pos].mx); return {l, pmn, pmx}; } int mid = (l + r) / 2; push(rpos, mid + 1, r); ll rmn = min(pmn, node[rpos].mn); ll rmx = max(pmx, node[rpos].mx); if (rmx - rmn >= lim) return sch_rdif(rpos, mid + 1, r, lim, pmn, pmx); else return sch_rdif(lpos, l, mid, lim, rmn, rmx); } pair<int, int> sch_rdif(int lim) { auto [lp, mn, mx] = sch_rdif(1, 0, q, lim); return {lp, que(0, lp) != mn}; } int sch(int pos, int l, int r, int L, int R, int ty, ll x, ll pval) { push(pos, L, R); if (l == L && r == R) { if (l == r) return l; int mid = (L + R) / 2; push(rpos, mid + 1, R); ll rval = (ty == 0 ? min(node[rpos].mn, pval) : max(node[rpos].mx, pval)); if (rval == x) return sch(rpos, mid + 1, r, mid + 1, R, ty, x, pval); else return sch(lpos, l, mid, L, mid, ty, x, rval); } int mid = (L + R) / 2; if (l > mid) return sch(rpos, l, r, mid + 1, R, ty, x, pval); push(rpos, mid + 1, R); ll rval = (ty == 0 ? min(node[rpos].mn, pval) : max(node[rpos].mx, pval)); if (rval == x) return sch(rpos, mid + 1, r, mid + 1, R, ty, x, pval); else return sch(lpos, l, mid, L, mid, ty, x, rval); } int sch(int l, int r, int ty) { ll x = que(1, l, r, 0, q, ty); return sch(1, l, r, 0, q, ty, x, (ty == 0 ? INF : -INF)); } vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) { n = c.size(), q = l.size(); FOR (i, 0, q - 1) { op[l[i]].pb(i + 1, v[i]); op[r[i] + 1].pb(i + 1, -v[i]); } vector<int> ans(n); FOR (i, 0, n - 1) { // debug(i); for (auto [p, x] : op[i]) { // debug("upd", p, x); upd(p, x); } if (node[1].mx - node[1].mn <= c[i]) { // debug("sch_mn"); int lp = sch_mn(); ans[i] = que(lp + 1, q); continue; } // debug("sch_rdif"); auto [lp, ty] = sch_rdif(c[i]); // debug("sch", lp, ty); int rp = sch(lp + 1, q, !ty); ans[i] = (ty == 0 ? c[i] : 0) + que(rp + 1, q); } return ans; } /* in1 3 10 15 13 2 0 2 20 0 1 -11 out1 0 4 13 */ #ifdef WAIMAI int main() { int n; assert(1 == scanf("%d", &n)); vector<int> c(n); for(int i = 0; i < n; ++i) { assert(scanf("%d", &c[i]) == 1); } int q; assert(1 == scanf("%d", &q)); vector<int> l(q), r(q), v(q); for(int i = 0; i < q; ++i) { assert(scanf("%d %d %d", &l[i], &r[i], &v[i]) == 3); } vector<int> ans = distribute_candies(c, l, r, v); for(int i = 0; i < n; ++i) { if (i > 0) { printf(" "); } printf("%d", ans[i]); } printf("\n"); fclose(stdout); return 0; } #endif
#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...