Submission #672326

#TimeUsernameProblemLanguageResultExecution timeMemory
672326FedShatTwo Antennas (JOI19_antennas)C++17
100 / 100
1408 ms41092 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, 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].ans = max(tree[v].ans, tree[v].mx - tree[v].push); tree[v].push = INF; } Node pull(const Node &vl, const Node &vr) { Node ans; ans.mx = max(vl.mx, vr.mx); ans.ans = max({vl.ans, vr.ans}); 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; 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...