Submission #1256428

#TimeUsernameProblemLanguageResultExecution timeMemory
1256428MisterReaperFood Court (JOI21_foodcourt)C++20
2 / 100
77 ms19780 KiB
// File W.cpp created on 11.08.2025 at 13:49:00
#include <bits/stdc++.h>

using i64 = long long;

#ifdef DEBUG 
    #include "/home/ahmetalp/Desktop/Workplace/debug.h"
#else
    #define debug(...) void(23)
#endif

constexpr int max_N = int(2E5) + 5;

struct node {
    std::pair<int, int> mn = {0, 0};
    i64 sum = 0, neg = 0, pos = 0;
    node() {}
    node(i64 x, int p) {
        mn = {x, p};
        sum = x;
        neg = std::min(0LL, x);
        pos = std::max(0LL, x);
    }
} tree[max_N << 1];

node operator+ (const node lhs, const node rhs) {
    node res;
    res.mn = std::min(lhs.mn, {rhs.mn.first + lhs.sum, rhs.mn.second});
    res.sum = lhs.sum + rhs.sum;
    res.neg = lhs.neg + rhs.neg;
    res.pos = lhs.pos + rhs.pos;
    return res;
}

#define def int mid = (l + r) >> 1, lv = v + 1, rv = v + ((mid - l + 1) << 1)
void build(int v, int l, int r) {
    if (l == r) {
        tree[v].mn.second = l;
        return;
    }
    def;
    build(lv, l, mid);
    build(rv, mid + 1, r);
    tree[v] = tree[lv] + tree[rv];
}

void modify(int v, int l, int r, int p, node x) {
    if (l == r) {
        tree[v] = x;
        return;
    }
    def;
    if (p <= mid) {
        modify(lv, l, mid, p, x);
    } else {
        modify(rv, mid + 1, r, p, x);
    }
    tree[v] = tree[lv] + tree[rv];
}

node get(int v, int l, int r, int ql, int qr) {
    if (ql == l && r == qr) {
        return tree[v];
    }
    def;
    if (qr <= mid) {
        return get(lv, l, mid, ql, qr);
    } else if (mid + 1 <= ql) {
        return get(rv, mid + 1, r, ql, qr);
    } else {
        return get(lv, l, mid, ql, mid)
            + get(rv, mid + 1, r, mid + 1, qr);
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int N, M, Q;
    std::cin >> N >> M >> Q;

    std::vector<std::array<int, 5>> qry(Q);
    for (int i = 0; i < Q; ++i) {
        int TP;
        std::cin >> TP;
        if (TP == 1) {
            int L, R, K, C;
            std::cin >> L >> R >> K >> C;
            --L, --R;
            qry[i] = {TP, L, R, K, C};
        } else if (TP == 2) {
            int L, R, K;
            std::cin >> L >> R >> K;
            --L, --R;
            qry[i] = {TP, L, R, K};
        } else {
            int A, B;
            std::cin >> A >> B;
            --A;
            qry[i] = {TP, A, B};
        }
    }

    build(0, 0, Q);

    std::vector<std::vector<std::pair<int, int>>> add(N + 1);
    std::vector<std::vector<int>> ask(N + 1);
    for (int i = 0; i < Q; ++i) {
        if (qry[i][0] == 1) {
            auto[TP, L, R, C, K] = qry[i];
            add[L].emplace_back(i, +1);
            add[R + 1].emplace_back(i, -1);
        } else if (qry[i][0] == 2) {
            auto[TP, L, R, K, _] = qry[i];
            add[L].emplace_back(i, +2);
            add[R + 1].emplace_back(i, -2);
        } else {
            auto[TP, A, B, _, __] = qry[i];
            ask[A].emplace_back(i);
        }
    }

    std::vector<int> ans(Q, -1);
    for (int i = 0; i < N; ++i) {
        debug(i);
        for (auto[j, b] : add[i]) {
            debug(j, b);
            if (std::abs(b) == +1) {
                auto[TP, L, R, C, K] = qry[j];
                if (b == +1) {
                    node nd(K, j + 1);
                    modify(0, 0, Q, j + 1, nd);
                } else {
                    node nd(0, j + 1);
                    modify(0, 0, Q, j + 1, nd);
                }
            } else {
                auto[TP, L, R, K, _] = qry[j];
                if (b == +2) {
                    node nd(-K, j + 1);
                    modify(0, 0, Q, j + 1, nd);
                } else {
                    node nd(0, j + 1);
                    modify(0, 0, Q, j + 1, nd);
                }
            }
            debug(1);
        }
        for (auto j : ask[i]) {
            debug(j);
            auto[TP, A, B, _, __] = qry[j];
            auto nd = get(0, 0, Q, 0, j + 1);
            int lst = nd.mn.second + 1;
            if (get(0, 0, Q, lst, j + 1).sum < B) {
                ans[j] = 0;
                continue;
            } 

            i64 src = B - get(0, 0, Q, lst, j + 1).neg;
            debug(lst, src);

            auto dfs = [&](auto&& self, int v, int l, int r) -> int {
                if (r < lst) {
                    return -1;
                } 
                if (lst <= l && src > tree[v].pos) {
                    src -= tree[v].pos;
                    return -1;
                }
                if (l == r) {
                    return l;
                }
                def;
                int res = self(self, lv, l, mid);
                if (res == -1) {
                    res = self(self, rv, mid + 1, r);
                }
                return res;
            };
            int res = dfs(dfs, 0, 0, Q);
            assert(res > 0);
            debug(qry[res - 1][3]);
            ans[j] = qry[res - 1][3];
        }
    }

    for (int i = 0; i < Q; ++i) {
        if (ans[i] != -1) {
            std::cout << ans[i] << '\n';
        }
    }

    return 0;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...