제출 #1221911

#제출 시각아이디문제언어결과실행 시간메모리
1221911madamadam3사탕 분배 (IOI21_candies)C++20
3 / 100
5097 ms27720 KiB
#include "candies.h"
#include <bits/stdc++.h>

using namespace std;

struct Node {
    int sum;       
    int lmin, lmax;        
    int umin, umax;      

    Node() : sum(0), lmin(INT_MAX), lmax(INT_MIN), umin(INT_MAX), umax(INT_MIN) {}
    Node(int val, int cap) : sum(val), lmin(val), lmax(val), umin(cap - val), umax(cap - val) {}

    Node(const Node& A, const Node& B) {
        sum  = A.sum + B.sum;
        lmin = min(A.lmin, A.lmin < INT_MAX ? B.lmin : INT_MAX);
        lmax = max(A.lmax, B.lmax);
        umin = min(A.umin, A.umin < INT_MAX ? B.umin : INT_MAX);
        umax = max(A.umax, B.umax);
    }
};

struct SegmentTree {
    int n; vector<int> arr, cap;
    vector<Node> st;
    vector<int> lazy;

    SegmentTree(int N, vector<int> &Cap) {
        n = N;
        cap = Cap;
        arr.assign(n, 0);
        st.assign(4*n, Node());
        lazy.assign(4*n, 0);
        build(0, 0, n);
    }

    Node build(int i, int l, int r) {
        if (l + 1 == r) return st[i] = Node(0, cap[l]);
        int m = l + (r - l) / 2;
        return st[i] = Node(build(2*i+1, l, m), build(2*i+2, m, r));
    }

    void apply_update(int i, int l, int r, int op) {
        int length = r - l;

        lazy[i] += op;
        st[i].sum += op * length;
        st[i].lmin += op;
        st[i].lmax += op;

        st[i].umin -= op;
        st[i].umax -= op;
    }

    void push_down(int i, int l, int r) {
        int m = l + (r - l) / 2;
        apply_update(2 * i + 1, l, m, lazy[i]);
        apply_update(2 * i + 2, m, r, lazy[i]);
        lazy[i] = 0;
    }

    Node query(int i, int l, int r, int ql, int qr) {
        if (qr <= l || r <= ql) return Node();
        if (ql <= l && r <= qr) return st[i];

        push_down(i, l, r);
        int m = l + (r - l) / 2;
        return Node(query(2*i+1, l, m, ql, qr), query(2*i+2, m, r, ql, qr));
    }

    Node upd_increase(int i, int l, int r, int ql, int qr, int qdelt) {
        if (qr <= l || r <= ql) return st[i];
        if (st[i].umax <= 0) return st[i];
        if (ql <= l && r <= qr && st[i].umin - qdelt >= 0) {
            apply_update(i, l, r, qdelt);
            return st[i];
        }

        if (l + 1 == r) {
            int nv = min(st[i].sum + qdelt, cap[l]);
            return st[i] = Node(nv, cap[l]);
        }

        push_down(i, l, r);
        int m = l + (r - l) / 2;
        return st[i] = Node(upd_increase(2*i+1, l, m, ql, qr, qdelt), upd_increase(2*i+2, m, r, ql, qr, qdelt));
    }

   Node upd_decrease(int i, int l, int r, int ql, int qr, int qdelt) {
        if (qr <= l || r <= ql) return st[i];
        if (st[i].lmax <= 0) return st[i];
        if (ql <= l && r <= qr && st[i].lmin + qdelt >= 0) {
            apply_update(i, l, r, qdelt);
            return st[i];
        }
        if (l + 1 == r) {
            int nv = max(st[i].sum + qdelt, 0);
            return st[i] = Node(nv, cap[l]);
        }

        push_down(i, l, r);
        int m = l + (r - l) / 2;
        return st[i] = Node(upd_decrease(2*i+1, l, m, ql, qr, qdelt), upd_decrease(2*i+2, m, r, ql, qr, qdelt));
    }

    void update(int l, int r, int delta) {
        if (delta < 0) upd_decrease(0, 0, n, l, r, delta);
        else upd_increase(0, 0, n, l, r, delta);
    }

    int query(int k) {
        return query(0, 0, n, k,k+1).sum;
    }
};

struct slow {
    int n; vector<int> cap, arr;

    slow(int N, vector<int> &cp) {
        n = N;
        cap = cp;
        arr.assign(n, 0);
    }

    void upd_increase(int l, int r, int delt) {
        for (int i = l; i <= r; i++) {
            arr[i] = min(arr[i] + delt, cap[i]);
        }
    }

    void upd_decrease(int l, int r, int delt) {
        for (int i = l; i <= r; i++) {
            arr[i] = max(arr[i] + delt, 0);
        }
    }

    void update(int l, int r, int delt) {
        if (delt < 0) upd_decrease(l, r, delt);
        else upd_increase(l, r, delt);
    }

    int query(int k) {
        return arr[k];
    }
};

vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) {
    int n = c.size(), q = v.size();
    vector<int> s(n);

    auto st = SegmentTree(n, c);
    // auto sl = slow(n, c);

    for (int i = 0; i < q; i++) {
        st.update(l[i], r[i]+1, v[i]);
        // sl.update(l[i], r[i], v[i]);
    }

    for (int i = 0; i < n; i++) {
        s[i] = st.query(i);
        // cout << st.query(i) << " ";
    }
    // cout << "\n";
    // for (int i = 0; i < n; i++) {
    //     cout << sl.query(i) << " ";
    // }
    // cout << "\n";
    // s = sl.arr;
    return s;
}
#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...