| # | Time | Username | Problem | Language | Result | Execution time | Memory | 
|---|---|---|---|---|---|---|---|
| 1241962 | hayford08 | Distributing Candies (IOI21_candies) | C++20 | 0 ms | 0 KiB | 
#include <vector>
#include <algorithm>
using namespace std;
const int INF = 1e9;
struct SegBeats {
    struct Node {
        int mx, sx, cnt_mx;
        int mn, sn, cnt_mn;
        long long sum;
        long long add;
    };
    int n;
    vector<Node> st;
    
    SegBeats(int _n): n(_n), st(4*n) {
        build(1, 0, n-1);
    }
    void build(int p, int L, int R) {
        auto &nd = st[p];
        nd.add = 0;
        nd.sum = 0;
        nd.mx = nd.mn = 0;
        nd.sx = -INF; nd.sn = INF;
        nd.cnt_mx = nd.cnt_mn = R-L+1;
        if (L==R) return;
        int M=(L+R)/2;
        build(p<<1, L, M);
        build(p<<1|1, M+1, R);
    }
    // push down lazy tags and chmin/chmax constraints
    void push(int p, int L, int R) {
        // apply pending add
        if (st[p].add) apply_add(p<<1, st[p].add);
        if (st[p].add) apply_add(p<<1|1, st[p].add);
        st[p].add = 0;
        // push down a chmin if current mx < child mx
        push_chmin(p<<1, st[p].mx);
        push_chmin(p<<1|1, st[p].mx);
        // push down a chmax if current mn > child mn
        push_chmax(p<<1, st[p].mn);
        push_chmax(p<<1|1, st[p].mn);
    }
    // apply range_add to node p
    void apply_add(int p, long long v) {
        auto &nd = st[p];
        nd.mx += v; nd.mn += v;
        if (nd.sx != -INF) nd.sx += v;
        if (nd.sn != INF) nd.sn += v;
        nd.sum += v * (nd.cnt_mx + (nd.sum - nd.mx * nd.cnt_mx) / (nd.mn)); 
        nd.add += v;
    }
    // apply chmin(x) to node p if needed
    void push_chmin(int p, int x) {
        auto &nd = st[p];
        if (nd.mx <= x) return;
        nd.sum -= 1LL*(nd.mx - x)*nd.cnt_mx;
        nd.mx = x;
        // if the new mx equals the second max, we may need to adjust sx/cnt
        if (nd.mx == nd.sx) {
            nd.sx = -INF;
            nd.cnt_mx += /*cnt of old sx*/;
        }
        // same logic for minima side if needed...
    }
    // apply chmax(x) similarly
    void push_chmax(int p, int x) { /* mirror of chmin */ }
    // pull up from children
    void pull(int p) {
        auto &nd = st[p];
        auto &L = st[p<<1], &R = st[p<<1|1];
        // update sum
        nd.sum = L.sum + R.sum;
        // update mx, cnt_mx, sx
        if (L.mx > R.mx) {
            nd.mx = L.mx; nd.cnt_mx = L.cnt_mx;
            nd.sx = max(L.sx, R.mx);
        } else if (R.mx > L.mx) {
            nd.mx = R.mx; nd.cnt_mx = R.cnt_mx;
            nd.sx = max(R.sx, L.mx);
        } else { // equal
            nd.mx = L.mx;
            nd.cnt_mx = L.cnt_mx + R.cnt_mx;
            nd.sx = max(L.sx, R.sx);
        }
        // update mn, cnt_mn, sn similarly...
    }
    // range add
    void range_add(int i, int j, int v) { upd_add(1,0,n-1,i,j,v); }
    void upd_add(int p, int L, int R, int i, int j, int v) {
        if (j< L || R< i) return;
        if (i <= L && R <= j) { apply_add(p, v); return; }
        push(p, L, R);
        int M=(L+R)/2;
        upd_add(p<<1, L, M, i, j, v);
        upd_add(p<<1|1, M+1, R, i, j, v);
        pull(p);
    }
    // range chmin
    void range_chmin(int i, int j, int x) { upd_chmin(1,0,n-1,i,j,x); }
    void upd_chmin(int p, int L, int R, int i, int j, int x) {
        if (j< L || R< i || st[p].mx <= x) return;
        if (i <= L && R <= j && st[p].sx < x) {
            push_chmin(p, x);
            return;
        }
        push(p, L, R);
        int M=(L+R)/2;
        upd_chmin(p<<1, L, M, i, j, x);
        upd_chmin(p<<1|1, M+1, R, i, j, x);
        pull(p);
    }
    // range chmax (mirror)
    void range_chmax(int i, int j, int x) { /* … */ }
    // finally, collect all leaves
    void collect(int p, int L, int R, vector<int>& out) {
        if (L==R) {
            out[L] = st[p].mx;  // == st[p].mn == final value
            return;
        }
        push(p, L, R);
        int M=(L+R)/2;
        collect(p<<1,   L,   M, out);
        collect(p<<1|1, M+1, R, out);
    }
};
// Usage:
vector<int> distribute_candies(
    const vector<int>& c,
    const vector<int>& l,
    const vector<int>& r,
    const vector<int>& v
) {
    int n = c.size(), q = l.size();
    int C = c[0];  // all capacities are the same
    SegBeats seg(n);
    for (int j = 0; j < q; j++) {
        if (v[j] > 0) {
            seg.range_add(l[j], r[j], v[j]);
            seg.range_chmin(l[j], r[j], C);
        } else {
            seg.range_add(l[j], r[j], v[j]);
            seg.range_chmax(l[j], r[j], 0);
        }
    }
    vector<int> ans(n);
    seg.collect(1, 0, n-1, ans);
    return ans;
}
