제출 #1332293

#제출 시각아이디문제언어결과실행 시간메모리
1332293MisterReaperTwo Antennas (JOI19_antennas)C++20
100 / 100
478 ms34772 KiB
#include <bits/stdc++.h>

using i64 = long long;

#ifdef LOCAL
    #include "debug.h"
#else
    #define debug(...) void(23)
#endif

constexpr int inf = int(1E9) + 5;

#define def int mid = (l + r) >> 1, lv = v + 1, rv = v + ((mid - l + 1) << 1)
struct segtree {
    struct node {
        int ans = -inf;
        int mn = -inf;
        int lz = -inf;
        void modify(int x) {
            ans = std::max(ans, x - mn);
            lz = std::max(lz, x);
        }
    };
    node unite(const node& lhs, const node& rhs) {
        node res;
        res.ans = std::max(lhs.ans, rhs.ans);
        res.mn = std::min(lhs.mn, rhs.mn);
        return res;
    }
    int n;
    std::vector<node> tree;
    segtree(int n_, std::vector<int>& vec) : n(n_), tree(n << 1) {
        auto dfs = [&](auto&& self, int v, int l, int r) -> void {
            if (l == r) {
                tree[v].ans = -inf - vec[l];
                tree[v].mn = inf + vec[l];
                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 != -inf) {
            tree[lv].modify(tree[v].lz);
            tree[rv].modify(tree[v].lz);
            tree[v].lz = -inf;
        }
    }
    void modify(int v, int l, int r, int ql, int qr, int 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, int x) {
        if (l > r) {
            return;
        }
        modify(0, 0, n - 1, l, r, x);
    }
    void add(int v, int l, int r, int p, int x) {
        if (l == r) {
            tree[v].mn += x;
            return;
        }
        def;
        push(v, l, r);
        if (p <= mid) {
            add(lv, l, mid, p, x);
        } else {
            add(rv, mid + 1, r, p, x);
        }
        tree[v] = unite(tree[lv], tree[rv]);
    }
    void add(int p, int x) {
        add(0, 0, n - 1, p, 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_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int N;
    std::cin >> N;

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

    int Q;
    std::cin >> Q;

    std::vector<int> L(Q), R(Q), ans(Q, -1);
    for (int q = 0; q < Q; ++q) {
        std::cin >> L[q] >> R[q];
        --L[q], --R[q];
    }

    auto work = [&]() -> void {
        segtree seg(N, H);
        std::vector<std::vector<int>> ask(N);
        std::vector<std::vector<int>> add(N + 1), del(N + 1);
        for (int i = 0; i < N; ++i) {
            add[std::min(N, i + A[i])].emplace_back(i);
            del[std::min(N, i + B[i] + 1)].emplace_back(i);
        }
        for (int i = 0; i < Q; ++i) {
            ask[R[i]].emplace_back(i);
        }

        for (int i = 0; i < N; ++i) {
            for (auto j : add[i]) {
                seg.add(j, -inf);
            }
            for (auto j : del[i]) {
                seg.add(j, +inf);
            }
            seg.modify(std::max(0, i - B[i]), std::max(-1, i - A[i]), H[i]);
            for (auto j : ask[i]) {
                debug(L[j], R[j], seg.get(L[j], R[j]).ans);
                ans[j] = std::max(ans[j], seg.get(L[j], R[j]).ans);
            }
        }

        std::reverse(H.begin(), H.end());
        std::reverse(A.begin(), A.end());
        std::reverse(B.begin(), B.end());
        for (int i = 0; i < Q; ++i) {
            L[i] = N - L[i] - 1;
            R[i] = N - R[i] - 1;
            std::swap(L[i], R[i]);
        }
        debug();
    };
    work();
    work();

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