제출 #672322

#제출 시각아이디문제언어결과실행 시간메모리
672322FedShatTwo Antennas (JOI19_antennas)C++17
13 / 100
3065 ms27548 KiB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
constexpr int INF = numeric_limits<int>::max() / 2;
constexpr ll INFLL = numeric_limits<ll>::max() / 2;

template<class T>
istream &operator>>(istream &is, vector<T> &a) {
    for (auto &i : a) {
        is >> i;
    }
    return is;
}

struct SegTree {
    struct Node {
        int mx = -INF, mn = INF, ans = -2 * INF, push = INF;
    };

    vector<Node> tree;
    vector<int> hx, ans;
    int n;

    SegTree(int n) : n(n) {
        hx.resize(n, -INF);
        ans.resize(n, -2 * INF);
        tree.resize(4 * n);
    }

    void push(int v, int l, int r) {// min=
        if (l + 1 < r) {
            tree[2 * v + 1].push = min(tree[v].push, tree[2 * v + 1].push);
            tree[2 * v + 2].push = min(tree[v].push, tree[2 * v + 2].push);
        }
        tree[v].mn = min(tree[v].mn, tree[v].push);
        tree[v].ans = max(tree[v].ans, tree[v].mx - tree[v].mn);
        tree[v].push = INF;
    }

    Node pull(const Node &vl, const Node &vr) {
        Node ans;
        ans.mn = min(vl.mn, vr.mn);
        ans.mx = max(vl.mx, vr.mx);
        ans.ans = max({vl.ans, vr.ans, ans.mx - ans.mn});
        return ans;
    }

    void update_seg(int v, int l, int r, int li, int ri, int x) {// min= x
        push(v, l, r);
        if (li >= r || l >= ri) {
            return;
        }
        if (li <= l && r <= ri) {
            tree[v].push = x;
            push(v, l, r);
            return;
        }
        int m = (l + r) / 2;
        update_seg(2 * v + 1, l, m, li, ri, x);
        update_seg(2 * v + 2, m, r, li, ri, x);
        tree[v] = pull(tree[2 * v + 1], tree[2 * v + 2]);
    }

    void update_seg(int li, int ri, int x) {
        li = max(li, 0);
        ri = min(ri + 1, n);
        for (int i = li; i < ri; ++i) {
            ans[i] = max(ans[i], hx[i] - x);
        }
        // update_seg(0, 0, n, li, ri, x);
    }

    void update_point(int v, int l, int r, int i, int x) {
        push(v, l, r);
        if (l + 1 == r) {
            tree[v].mx = x;
            tree[v].ans = max(tree[v].ans, tree[v].mx - tree[v].mn);
            return;
        }
        int m = (l + r) / 2;
        {
            push(2 * v + 1, l, m);
            push(2 * v + 2, m, r);
        }
        if (i < m) {
            update_point(2 * v + 1, l, m, i, x);
        } else {
            update_point(2 * v + 2, m, r, i, x);
        }
        tree[v] = pull(tree[2 * v + 1], tree[2 * v + 2]);
    }

    void update_point(int i, int x) {
        hx[i] = x;
        // update_point(0, 0, n, i, x);
    }

    int get(int v, int l, int r, int li, int ri) {
        push(v, l, r);
        if (li >= r || l >= ri) {
            return -2 * INF;
        }
        if (li <= l && r <= ri) {
            return tree[v].ans;
        }
        int m = (l + r) / 2;
        return max(get(2 * v + 1, l, m, li, ri), get(2 * v + 2, m, r, li, ri));
    }

    int get(int li, int ri) {
        int res = -2 * INF;
        for (int i = li; i < ri; ++i) {
            res = max(res, ans[i]);
        }
        return res;
        // return get(0, 0, n, li, ri);
    }
};

struct Event {
    int x;
    int t;// -1 is opened, +1 is closed, 0 is new point, 2 is query
    int i;
    int l;// for query

    bool operator<(const Event &p) const {
        return x < p.x || (x == p.x && t < p.t);
    }
};

int main() {
    cin.tie(0)->sync_with_stdio(0);
#ifdef __APPLE__
    freopen("input.txt", "r", stdin);
#endif
    int n;
    cin >> n;
    vector<array<int, 3>> hab(n);
    for (int i = 0; i < n; ++i) {
        cin >> hab[i][0] >> hab[i][1] >> hab[i][2];
    }
    int q;
    cin >> q;
    vector<pair<int, int>> lr(q);
    for (int i = 0; i < q; ++i) {
        cin >> lr[i].first >> lr[i].second;
        --lr[i].first;
        --lr[i].second;
    }
    vector<int> ans(q, -2 * INF);
    auto solve = [&]() {
        vector<Event> e;
        for (int i = 0; i < n; ++i) {
            e.push_back({i, 0, i, -1});
            e.push_back({i + hab[i][1], -1, i, -1});
            e.push_back({i + hab[i][2], +1, i, -1});
        }
        for (int i = 0; i < q; ++i) {
            e.push_back({lr[i].second, 2, i, lr[i].first});
        }
        sort(e.begin(), e.end());
        SegTree st(n);
        for (auto [x, t, i, l] : e) {
            // cout << x << " " << t << " " << i << " " << l << "\n";
            if (t == -1) {
                st.update_point(i, hab[i][0]);
            } else if (t == 1) {
                st.update_point(i, -INF);
            } else if (t == 0) {
                st.update_seg(x - hab[i][2], x - hab[i][1], hab[i][0]);
            } else {
                ans[i] = max(ans[i], st.get(l, x + 1));
            }
        }
    };
    solve();
    for (auto &[l, r] : lr) {
        l = n - l - 1;
        r = n - r - 1;
        swap(l, r);
    }
    reverse(hab.begin(), hab.end());
    solve();
    for (auto i : ans) {
        cout << max(-1, i) << "\n";
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...