제출 #375007

#제출 시각아이디문제언어결과실행 시간메모리
375007vot808Two Antennas (JOI19_antennas)C++17
100 / 100
1046 ms56028 KiB
#include "bits/stdc++.h" using namespace std; #define for_(i, s, e) for (int i = s; i < (int) e; i++) #define for__(i, s, e) for (ll i = s; i < e; i++) typedef long long ll; typedef vector<int> vi; typedef array<int, 2> ii; #define endl '\n' const ll INF = 1e15; struct Node { ll ans = -INF, mn = INF; }; class SegmentTree { public: vector<Node> tree; int n; vector<ll> lazy; Node merge(Node &a, Node &b) { Node ans; ans.ans = max(a.ans, b.ans); ans.mn = min(a.mn, b.mn); return ans; } void push(int &p, int &c1, int &c2) { if (lazy[p] != -INF) { lazy[c1] = max(lazy[c1], lazy[p]); lazy[c2] = max(lazy[c2], lazy[p]); tree[c1].ans = max(tree[c1].ans, lazy[c1]-tree[c1].mn); tree[c2].ans = max(tree[c2].ans, lazy[c2]-tree[c2].mn); lazy[p] = -INF; } } void updateMin(int i, ll val, int l, int r, int p) { if (l > i or r < i) return; if (l == r) { lazy[p] = -INF; if (val != INF) tree[p].ans = -INF; tree[p].mn = val; return; } int mid = (l + r) / 2; int c1 = 2*p+1, c2 = 2*p+2; push(p, c1, c2); updateMin(i, val, l, mid, c1); updateMin(i, val, mid+1, r, c2); tree[p] = merge(tree[c1], tree[c2]); } void updateRangeMax(int i, int j, ll val, int l, int r, int p) { if (r < i or l > j) return; if (l >= i and r <= j) { lazy[p] = max(lazy[p], val); tree[p].ans = max(tree[p].ans, lazy[p]-tree[p].mn); return; } int mid = (l + r) / 2; int c1 = 2*p+1, c2 = 2*p+2; push(p, c1, c2); updateRangeMax(i, j, val, l, mid, c1); updateRangeMax(i, j, val, mid+1, r, c2); tree[p] = merge(tree[c1], tree[c2]); } ll ans(int i, int j, int l, int r, int p) { if (l > j or r < i) return -INF; if (l >= i and r <= j) return tree[p].ans; int mid = (l + r) / 2; int c1 = 2*p+1, c2 = 2*p+2; push(p, c1, c2); return max(ans(i, j, l, mid, c1), ans(i, j, mid+1, r, c2)); } SegmentTree(int N) { n = N; tree.resize(4*n); lazy.resize(4*n, -INF); } }; int n, q; vector<array<int, 3>> nums; // {height, a, b} vector<ii> qrs; vector<ll> ans; void solve() { SegmentTree tree(n); vector<vector<array<int, 2>>> qrLeft(n); for_(i, 0, q) qrLeft[qrs[i][1]].push_back({qrs[i][0], i}); vector<vi> enter(n), bye(n); for_(i, 0, n) { if (i+nums[i][1] < n) enter[i+nums[i][1]].push_back(i); if (i+nums[i][1] < n-1) bye[min(i+nums[i][2], n-1)].push_back(i); } for_(i, 0, n) { for (auto &e: enter[i]) tree.updateMin(e, nums[e][0], 0, n-1, 0); if (i-nums[i][1] >= 0) tree.updateRangeMax(max(i-nums[i][2], 0), i-nums[i][1], nums[i][0], 0, n-1, 0); for (auto &l: qrLeft[i]) ans[l[1]] = max(ans[l[1]], tree.ans(l[0], i, 0, n-1, 0)); for (auto &e: bye[i]) tree.updateMin(e, INF, 0, n-1, 0); } } int main() { #ifdef mlocal freopen("test.in", "r", stdin); #endif ios_base::sync_with_stdio(false); cin.tie(0); cin >> n; nums.resize(n); for_(i, 0, n) cin >> nums[i][0] >> nums[i][1] >> nums[i][2]; cin >> q; qrs.resize(q); ans.resize(q, -1); for_(i, 0, q) { cin >> qrs[i][0] >> qrs[i][1]; qrs[i][0] -= 1; qrs[i][1] -= 1; } solve(); reverse(nums.begin(), nums.end()); for_(i, 0, q) { qrs[i][0] = n-1-qrs[i][0]; qrs[i][1] = n-1-qrs[i][1]; swap(qrs[i][0], qrs[i][1]); } solve(); for (auto i: ans) cout << i << endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...