Submission #1254899

#TimeUsernameProblemLanguageResultExecution timeMemory
1254899chikien2009Two Antennas (JOI19_antennas)C++20
100 / 100
312 ms40980 KiB
#include <bits/stdc++.h>

using namespace std;

void setup()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

struct SEGMENT_TREE
{
    int mx[800000], mn[800000], bmx[800000], bmn[800000], val[800000], block[800000];
    inline SEGMENT_TREE()
    {
        fill_n(val, 8e5, -1);
        fill_n(block, 8e5, 1);
        fill_n(bmx, 8e5, -2e9);
        fill_n(mx, 8e5, -2e9);
        fill_n(bmn, 8e5, 2e9);
        fill_n(mn, 8e5, 2e9);
    }
    inline void Join(int ind)
    {
        block[ind] = block[ind << 1] & block[ind << 1 | 1];
        bmx[ind] = max(bmx[ind << 1], bmx[ind << 1 | 1]);
        bmn[ind] = min(bmn[ind << 1], bmn[ind << 1 | 1]);
        val[ind] = max(val[ind << 1], val[ind << 1 | 1]);
    }
    inline void UpdateNode(int ind, int l, int r)
    {
        if (!block[ind] && mx[ind] != -2e9)
        {
            val[ind] = max({val[ind], abs(mx[ind] - bmn[ind]), abs(mn[ind] - bmx[ind])});
            if (l < r)
            {
                mx[ind << 1] = max(mx[ind << 1], mx[ind]);
                mx[ind << 1 | 1] = max(mx[ind << 1 | 1], mx[ind]);
                mn[ind << 1] = min(mn[ind << 1], mn[ind]);
                mn[ind << 1 | 1] = min(mn[ind << 1 | 1], mn[ind]);
            }
        }
        mx[ind] = -2e9;
        mn[ind] = 2e9;
    }
    inline void Set(int ind, int l, int r, int x, int v)
    {
        UpdateNode(ind, l, r);
        if (r < x || x < l)
        {
            return;
        }
        if (l == r)
        {
            bmx[ind] = bmn[ind] = v;
            block[ind] = false;
            return;
        }
        int m = (l + r) >> 1;
        Set(ind << 1, l, m, x, v);
        Set(ind << 1 | 1, m + 1, r, x, v);
        Join(ind);
    }
    inline void Block(int ind, int l, int r, int x)
    {
        UpdateNode(ind, l, r);
        if (r < x || x < l)
        {
            return;
        }
        if (l == r)
        {
            block[ind] = true;
            bmx[ind] = -2e9;
            bmn[ind] = 2e9;
            return;
        }
        int m = (l + r) >> 1;
        Block(ind << 1, l, m, x);
        Block(ind << 1 | 1, m + 1, r, x);
        Join(ind);
    }
    inline void Update(int ind, int l, int r, int x, int y, int v)
    {
        UpdateNode(ind, l, r);
        if (r < x || y < l || block[ind])
        {
            return;
        }
        if (x <= l && r <= y)
        {
            mx[ind] = mn[ind] = v;
            UpdateNode(ind, l, r);
            return;
        }
        int m = (l + r) >> 1;
        Update(ind << 1, l, m, x, y, v);
        Update(ind << 1 | 1, m + 1, r, x, y, v);
        Join(ind);
    }
    inline int Get(int ind, int l, int r, int x, int y)
    {
        UpdateNode(ind, l, r);
        if (r < x || y < l)
        {
            return -1;
        }
        if (x <= l && r <= y)
        {
            return val[ind];
        }
        int m = (l + r) >> 1;
        return max(Get(ind << 1, l, m, x, y), Get(ind << 1 | 1, m + 1, r, x, y));
    }
} st;

int n, q, h[200001], a[200001], b[200001], res[200000];
array<int, 3> query[200000];
vector<int> s[200002], e[200002];

int main()
{
    setup();

    cin >> n;
    for (int i = 1; i <= n; ++i)
    {
        cin >> h[i] >> a[i] >> b[i];
        s[min(n + 1, i + a[i])].push_back(i);
        e[min(n + 1, i + b[i] + 1)].push_back(i);
    }
    cin >> q;
    for (int i = 0; i < q; ++i)
    {
        cin >> query[i][1] >> query[i][0];
        query[i][2] = i;
    }
    sort(query, query + q);
    for (int i = 1, j = 0; i <= n; ++i)
    {
        for (auto &k : s[i])
        {
            st.Set(1, 1, n, k, h[k]);
        }
        for (auto &k : e[i])
        {
            st.Block(1, 1, n, k);
        }
        st.Update(1, 1, n, max(0, i - b[i]), max(0, i - a[i]), h[i]);
        while (j < q && query[j][0] == i)
        {
            res[query[j][2]] = st.Get(1, 1, n, query[j][1], query[j][0]);
            j++;
        }
    }
    for (int i = 0; i < q; ++i)
    {
        cout << res[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...