제출 #1344068

#제출 시각아이디문제언어결과실행 시간메모리
1344068MisterReaperFish 3 (JOI24_fish3)C++20
100 / 100
597 ms58780 KiB
#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(3E5) + 5;
constexpr i64 inf = i64(1E18);

int N;
i64 D;
i64 A[max_N];
int Q;
int L[max_N];
int R[max_N];
i64 ans[max_N];
std::vector<int> ask[max_N];

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

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

    std::cin >> N >> D;

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

    std::cin >> Q;

    for (int i = 0; i < Q; ++i) {
        std::cin >> L[i] >> R[i];
        --L[i], --R[i];
        ask[R[i]].emplace_back(i);
    }

    segtree sega(N);
    segtree segans(N);

    for (int i = 0; i < N; ++i) {
        sega.modify(i, i, A[i]);
    }

    std::vector<std::pair<int, i64>> stk;
    stk.emplace_back(0, inf);
    std::vector<i64> sum(N);
    for (int i = 1; i < N; ++i) {
        if (A[i - 1] <= A[i]) {
            stk.emplace_back(i, (A[i] - A[i - 1]) / D);
        } else {
            i64 need = (A[i - 1] - A[i] + D - 1) / D;
            while (need) {
                auto&[j, v] = stk.back();
                i64 use = std::min(v, need);
                sega.modify(j, i - 1, -use * D);
                segans.modify(j, i - 1, use);
                // for (int k = j; k < i; ++k) {
                //     A[k] -= use * D;
                //     sum[k] += use;
                // }
                v -= use;
                need -= use;
                if (v == 0) {
                    stk.pop_back();
                }
            }
        }
        for (auto j : ask[i]) {
            if (sega.get(L[j], L[j]).sum < 0) {
                ans[j] = -1;
            } else {
                ans[j] = segans.get(L[j], i).sum;
            }
            // if (A[L[j]] < 0) {
            //     ans[j] = -1;
            // } else {
            //     i64 res = 0;
            //     for (int k = j; k <= i; ++k) {
            //         res += sum[k];
            //     }
            //     ans[j] = res;
            // }
        }
    }

    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...