Submission #1253448

#TimeUsernameProblemLanguageResultExecution timeMemory
1253448ankiteTriple Jump (JOI19_jumps)C++20
27 / 100
89 ms83104 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll NEG_INF = -(ll)1e18;

struct SegmentTree {
    int n, size;
    vector<ll> data;

    SegmentTree(int _n) {
        n = _n;
        size = 1;
        while (size < n) size <<= 1;
        data.assign(2 * size, NEG_INF);
    }

    void update(int i, ll val) {
        i += size;
        data[i] = max(data[i], val);
        for (i >>= 1; i > 0; i >>= 1)
            data[i] = max(data[2*i], data[2*i + 1]);
    }

    ll query(int l, int r) {
        ll res = NEG_INF;
        l += size; r += size;
        while (l <= r) {
            if (l & 1) res = max(res, data[l++]);
            if (!(r & 1)) res = max(res, data[r--]);
            l >>= 1;
            r >>= 1;
        }
        return res;
    }
};

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

    int n;
    if (!(cin >> n)) return 0;
    vector<ll> A(n);
    for (int i = 0; i < n; i++) cin >> A[i];
    int q;
    cin >> q;
    vector<tuple<int,int,int>> queries(q);
    for (int i = 0; i < q; i++) {
        int L, R;
        cin >> L >> R;
        --L; --R;
        queries[i] = {L, R, i};
    }

    int LOG = __lg(n) + 1;
    vector<vector<pair<ll,int>>> st_table(LOG, vector<pair<ll,int>>(n));
    for (int i = 0; i < n; i++) {
        st_table[0][i] = {A[i], i};
    }
    for (int j = 1; j < LOG; j++) {
        int step = 1 << (j - 1);
        for (int i = 0; i + (1 << j) <= n; i++) {
            auto [lv, li] = st_table[j-1][i];
            auto [rv, ri] = st_table[j-1][i + step];
            if (lv > rv)
                st_table[j][i] = {lv, li};
            else if (rv > lv)
                st_table[j][i] = {rv, ri};
            else
                st_table[j][i] = {lv, min(li, ri)};
        }
    }
    auto query_range_max = [&](int l, int r) {
        if (l > r) return make_pair(NEG_INF, -1);
        int len = r - l + 1;
        int j = __lg(len);
        auto seg1 = st_table[j][l];
        auto seg2 = st_table[j][r - (1 << j) + 1];
        if (seg1.first > seg2.first) return seg1;
        if (seg2.first > seg1.first) return seg2;
        return make_pair(seg1.first, min(seg1.second, seg2.second));
    };

    vector<vector<int>> nxt(n);
    vector<int> stck;
    for (int i = 0; i < n; i++) {
        while (!stck.empty() && A[stck.back()] < A[i]) {
            nxt[stck.back()].push_back(i);
            stck.pop_back();
        }
        if (!stck.empty()) {
            nxt[stck.back()].push_back(i);
        }
        stck.push_back(i);
    }

    vector<tuple<int,int,ll>> events;
    events.reserve(n);
    for (int i = 0; i < n; i++) {
        for (int j : nxt[i]) {
            int k_low = 2*j - i;
            if (k_low < n) {
                auto [val, idx] = query_range_max(k_low, n-1);
                ll total = A[i] + A[j] + val;
                events.emplace_back(idx, i, total);
            }
        }
    }
    sort(events.begin(), events.end(), [](auto &a, auto &b){ return get<0>(a) < get<0>(b); });

    auto queries_sorted = queries;
    sort(queries_sorted.begin(), queries_sorted.end(), [](auto &a, auto &b){
        return get<1>(a) < get<1>(b);
    });

    SegmentTree seg(n);
    vector<ll> ans(q, NEG_INF);
    int e_ptr = 0, qry_ptr = 0;

    for (int R = 0; R < n; R++) {
        while (e_ptr < (int)events.size() && get<0>(events[e_ptr]) <= R) {
            int i = get<1>(events[e_ptr]);
            ll v = get<2>(events[e_ptr]);
            seg.update(i, v);
            e_ptr++;
        }
        while (qry_ptr < q && get<1>(queries_sorted[qry_ptr]) == R) {
            int l0, r0, idx;
            tie(l0, r0, idx) = queries_sorted[qry_ptr];
            ans[idx] = seg.query(l0, n-1);
            qry_ptr++;
        }
    }

    for (ll x : ans) {
        cout << x << "\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...