제출 #1275179

#제출 시각아이디문제언어결과실행 시간메모리
1275179MisterReaperFire (JOI20_ho_t5)C++20
100 / 100
469 ms41320 KiB
// File fire.cpp created on 01.10.2025 at 10:44:35
#include <bits/stdc++.h>

using i64 = long long;

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

#define def int mid = (l + r) >> 1, lv = v + 1, rv = v + ((mid - l + 1) << 1)

struct segtree {
    struct node {
        i64 sum = 0;
        i64 lz = 0;
    };
    node unite(const node& lhs, const node& rhs) {
        node res;
        res.sum = lhs.sum + rhs.sum;
        return res;
    }
    int n;
    std::vector<node> tree;
    segtree(int n_) : n(n_), tree(n << 1) {}
    void push(int v, int l, int r) {
        def;
        i64 x = tree[v].lz;
        tree[lv].sum += (mid - l + 1) * x;
        tree[lv].lz += x;
        tree[rv].sum += (r - mid) * x;
        tree[rv].lz += x;
        tree[v].lz = 0;
    }
    void modify(int v, int l, int r, int ql, int qr, i64 x) {
        if (ql == l && r == qr) {
            tree[v].sum += (r - l + 1) * x;
            tree[v].lz += x;
            return;
        }
        def;
        push(v, l, r);
        if (qr <= mid) {
            modify(lv, l, mid, ql, qr, x);
        } else if (mid + 1 <= ql) {
            modify(rv, mid + 1, r, ql, qr, x);
        } else {
            modify(lv, l, mid, ql, mid, x);
            modify(rv, mid + 1, r, mid + 1, qr, x);
        }
        tree[v] = unite(tree[lv], tree[rv]);
    }
    void modify(int l, int r, i64 x) {
        assert(0 <= l && l <= r && r < n);
        modify(0, 0, n - 1, l, r, x);
    }
    i64 get(int v, int l, int r, int ql, int qr) {
        if (l == ql && qr == r) {
            return tree[v].sum;
        }
        def;
        push(v, l, r);
        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);
        }
    }
    i64 get(int l, int r) {
        if (r < l) {
            return 0;
        }
        return get(0, 0, n - 1, l, r);
    } 
};

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

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

    std::vector<int> A(N);
    for (int i = 0; i < N; ++i) {
        std::cin >> A[i];
    }

    std::vector<i64> ans(Q);
    std::vector<std::vector<std::pair<int, int>>> sp(N);
    std::vector<std::array<int, 3>> qry(Q);
    for (int i = 0; i < Q; ++i) {
        int T, L, R;
        std::cin >> T >> L >> R;
        --L, --R;
        qry[i] = {T, L, R};
        if (L) {
            sp[L - 1].emplace_back(i, -1);
        }
        sp[R].emplace_back(i, +1);
    }

    i64 sum = 0, delta = 0;
    segtree seg1(N + 1);
    segtree seg2(N + 2);
    segtree seg3(N + 1);
    std::vector<int> prv(N);
    std::vector<int> stk {-1};
    std::vector<std::array<int, 3>> rngs(N);
    for (int i = 0; i < N; ++i) {
        sum += A[i];
        while (stk.size() > 1 && A[stk.back()] < A[i]) {
            auto j = stk.back();
            sum -= -1LL * rngs[j][2] * (j - 1);
            delta -= rngs[j][2];
            seg2.modify(0, rngs[j][0] - 1, -rngs[j][2]);
            seg3.modify(prv[j] + 1, N, -rngs[j][2]);

            rngs[j][1] = i - j;
            seg1.modify(rngs[j][0], rngs[j][0] + rngs[j][1] - 1, rngs[j][2]);
            stk.pop_back();
        }
        prv[i] = stk.back();
        rngs[i][0] = i - stk.back();
        rngs[i][1] = N + 1;
        rngs[i][2] = (stk.back() == -1 ? 0 : A[stk.back()] - A[i]);
        // min(t - tl + 1, j - i + 1)
        // = -max(j - t - par, 0) + j - i + 1
        sum += -1LL * rngs[i][2] * (i - 1);
        delta += rngs[i][2];
        seg2.modify(0, rngs[i][0] - 1, rngs[i][2]);
        seg3.modify(prv[i] + 1, N, rngs[i][2]);
        stk.emplace_back(i);

        for (auto[qq, dt] : sp[i]) {
            int t = qry[qq][0];
            i64 qsum = sum + seg1.get(0, t) + seg2.get(t + 1, N + 1) + 1LL * i * delta - seg3.get(0, i - t); 
            debug(qq, qsum);
            debug(sum, seg1.get(0, t), seg2.get(t + 1, N + 1), 1LL * i * delta, -seg3.get(0, i - t));
            ans[qq] += dt * qsum;
        }
        debug();
    }

    for (int i = 0; i < Q; ++i) {
        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...