Submission #1364293

#TimeUsernameProblemLanguageResultExecution timeMemory
1364293iamhereforfunTwo Antennas (JOI19_antennas)C++20
22 / 100
260 ms43192 KiB
// Starcraft 2 enjoyer //

#include <bits/stdc++.h>

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")

using namespace std;

#define LSOne(X) ((X) & -(X))
#define int long long

const int N = 2e5 + 5;
const int M = 11;
const int B = 18;
const long long K = 2;
const int LG = 20;
const long long INF = 1e18 + 5;
const int P = 31;
const int MOD = 998244353;
const int nx[] = {0, 1, 0, -1}, ny[] = {-1, 0, 1, 0};

struct Node
{
    int ans, mx, lazy;
    Node operator+(Node a)
    {
        Node nd;
        nd.ans = max(a.ans, ans);
        nd.mx = max(a.mx, mx);
        nd.lazy = INF + 1;
        return nd;
    }
};

struct SegmentTree
{
    vector<Node> st;
    int n;
    void build(int v, int l, int r)
    {
        if (l == r)
        {
            st[v].ans = -1;
            st[v].mx = 0;
            st[v].lazy = INF + 1;
        }
        else
        {
            int m = (l + r) / 2;
            build(2 * v, l, m);
            build(2 * v + 1, m + 1, r);
            st[v].ans = -1;
            st[v] = st[2 * v] + st[2 * v + 1];
        }
    }
    void cal(int v)
    {
        st[v].ans = max(st[v].ans, st[v].mx - st[v].lazy);
        // cout << st[v].ans << "\n";
        st[v].lazy = INF + 1;
    }
    void prop(int v, int l, int r)
    {
        if (l != r)
        {
            cal(2 * v);
            cal(2 * v + 1);
            st[2 * v].lazy = st[v].lazy;
            st[2 * v + 1].lazy = st[v].lazy;
        }
        cal(v);
        st[v].lazy = INF + 1;
        if (l != r)
        {
            int a = st[v].ans;
            st[v] = st[2 * v] + st[2 * v + 1];
            st[v].ans = max(st[v].ans, a);
        }
    }
    void update1(int v, int val, int pos, int l, int r)
    {
        prop(v, l, r);
        if (l == r)
        {
            st[v].mx = val;
        }
        else
        {
            int m = (l + r) / 2;
            if (pos <= m)
            {
                update1(2 * v, val, pos, l, m);
            }
            else
            {
                update1(2 * v + 1, val, pos, m + 1, r);
            }
            int a = st[v].ans;
            st[v] = st[2 * v] + st[2 * v + 1];
            st[v].ans = max(st[v].ans, a);
        }
    }
    void update2(int v, int val, int l, int r, int tl, int tr)
    {
        prop(v, l, r);
        if (tl > tr)
            return;
        if (tl <= l && r <= tr)
        {
            st[v].lazy = min(st[v].lazy, val);
            prop(v, l, r);
        }
        else
        {
            int m = (l + r) / 2;
            update2(2 * v, val, l, m, tl, min(tr, m));
            update2(2 * v + 1, val, m + 1, r, max(tl, m + 1), tr);
            int a = st[v].ans;
            st[v] = st[2 * v] + st[2 * v + 1];
            st[v].ans = max(st[v].ans, a);
        }
    }
    int get(int v, int l, int r, int tl, int tr)
    {
        prop(v, l, r);
        if (tl > tr)
            return -1;
        if (tl <= l && r <= tr)
        {
            return st[v].ans;
        }
        else
        {
            int m = (l + r) / 2;
            return max(get(2 * v, l, m, tl, min(tr, m)), get(2 * v + 1, m + 1, r, max(tl, m + 1), tr));
        }
    }

    SegmentTree(int len)
    {
        n = len;
        st.assign(4 * n, {});
        build(1, 0, n - 1);
    }
    void update1(int val, int pos)
    {
        update1(1, val, pos, 0, n - 1);
    }
    void update2(int val, int l, int r)
    {
        update2(1, val, 0, n - 1, l, r);
    }
    int get(int l, int r)
    {
        return get(1, 0, n - 1, l, r);
    }
};

int n, q, ans[N];
array<int, 3> ant[N];
pair<int, int> query[N];
vector<pair<int, int>> ask[N], update[N];

inline void solve()
{
    cin >> n;
    for (int x = 0; x < n; x++)
    {
        int h, a, b;
        cin >> h >> a >> b;
        ant[x] = {h, a, b};
    }
    cin >> q;
    for (int x = 0; x < q; x++)
    {
        int a, b;
        cin >> a >> b;
        a--;
        b--;
        ans[x] = -1;
        query[x] = {a, b};
    }
    for (int x = 0; x < 2; x++)
    {
        SegmentTree st(n);
        for (int y = 0; y < n; y++)
        {
            update[y].clear();
            ask[y].clear();
        }
        for (int y = 0; y < n; y++)
        {
            auto [h, a, b] = ant[y];
            update[min(n, y + a)].push_back({h, y});
            update[min(n, y + b + 1)].push_back({0, y});
        }
        for (int y = 0; y < q; y++)
        {
            auto [a, b] = query[y];
            ask[b].push_back({a, y});
        }
        for (int y = 0; y < n; y++)
        {
            // cout << y << "www\n";
            for (auto &[v, p] : update[y])
            {
                st.update1(v, p);
            }
            auto &[h, a, b] = ant[y];
            st.update2(h, max(0LL, y - b), max(0LL, y - a));
            // cout << h << " " << max(0LL, y - b) << " " << max(0LL, y - a) << " " << "updat2\n";
            for (auto &[l, id] : ask[y])
            {
                // cout << "ASK " << l << " " << y << " " << st.get(l, y) << "\n";
                ans[id] = max(ans[id], st.get(l, y));
            }
            // cout << y << " " << st.get(0, y) << " " << h << " " << a << " " << b << "\n";
        }
        // cout << "\n";
        reverse(ant, ant + n);
        for (int y = 0; y < q; y++)
        {
            auto &[a, b] = query[y];
            a = n - 1 - a;
            b = n - 1 - b;
            // cout << a << " " << b << "bruhbruh\n";
            swap(a, b);
        }
    }
    for (int x = 0; x < q; x++)
    {
        cout << ans[x] << "\n";
    }
}

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    for (int x = 1; x <= t; x++)
    {
        solve();
    }
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...