제출 #332890

#제출 시각아이디문제언어결과실행 시간메모리
33289012tqianTwo Antennas (JOI19_antennas)C++17
100 / 100
1267 ms28180 KiB
#include <bits/stdc++.h> const int INF = 1e9; template <class T> struct LazySeg { int sz; std::vector<T> c; // stores max of c std::vector<T> d; // stores max of d std::vector<T> lazy; // stores what you subtract max with void init(int n) { sz = 1; while (sz < n) sz *= 2; c.assign(2 * sz, -INF); d.assign(2 * sz, -INF); lazy.assign(2 * sz, -INF); } void pull(int ind) { c[ind] = std::max(c[2 * ind], c[2 * ind + 1]); d[ind] = std::max(d[2 * ind], d[2 * ind + 1]); } void push(int ind, int L, int R) { d[ind] = std::max(d[ind], c[ind] + lazy[ind]); if (L != R) { lazy[2 * ind] = std::max(lazy[2 * ind], lazy[ind]); lazy[2 * ind + 1] = std::max(lazy[2 * ind + 1], lazy[ind]); } lazy[ind] = -INF; } void set(int p, T val, int ind = 1, int L = 0, int R = -1) { if (R == -1) R += sz; push(ind, L, R); if (p < L || R < p) return; if (L == R) { c[ind] = val; // push(ind, L, R); return; } int M = (L + R) / 2; set(p, val, 2 * ind, L, M); set(p, val, 2 * ind + 1, M + 1, R); pull(ind); } void set_max(int lo, int hi, T val, int ind = 1, int L = 0, int R = -1) { if (R == -1) R += sz; push(ind, L, R); if (R < lo || hi < L) return; if (lo <= L && R <= hi) { lazy[ind] = val; push(ind, L, R); return; } int M = (L + R) / 2; set_max(lo, hi, val, 2 * ind, L, M); set_max(lo, hi, val, 2 * ind + 1, M + 1, R); pull(ind); } T qmax(int t, int lo, int hi, int ind = 1, int L = 0, int R = -1) { if (R == -1) R += sz; push(ind, L, R); if (R < lo || hi < L) return -INF; if (lo <= L && R <= hi) return (t == 0 ? c[ind] : d[ind]); int M = (L + R) / 2; return std::max(qmax(t, lo, hi, 2 * ind, L, M), qmax(t, lo, hi, 2 * ind + 1, M + 1, R)); } }; int main() { using namespace std; ios_base::sync_with_stdio(0); int n; cin >> n; vector<int> h(n), a(n), b(n); for (int i = 0; i < n; i++) cin >> h[i] >> a[i] >> b[i]; int q; cin >> q; vector<array<int, 2>> queries(q); for (int i = 0; i < q; i++) cin >> queries[i][0] >> queries[i][1], queries[i][0]--, queries[i][1]--; vector<int> ans(q, -1); LazySeg<int> seg; int tt = 0; auto solve = [&]() { tt++; seg.init(n); vector<vector<array<int, 2>>> events(n); for (int i = 0; i < n; i++) { if (i + a[i] < n) events[i + a[i]].push_back({1, i}); if (i + b[i] < n) events[i + b[i]].push_back({3, i}); events[i].push_back({2, i}); } for (int i = 0; i < q; i++) events[queries[i][1]].push_back({4, i}); for (auto& v : events) sort(v.begin(), v.end()); for (int j = 0; j < n; j++) { for (auto& e : events[j]) { int id = e[1]; if (e[0] == 1) { seg.set(id, h[id]); } else if (e[0] == 2) { int l = max(0, j - b[id]); int r = j - a[id]; if (l <= r) { seg.set_max(l, r, -h[id]); } } else if (e[0] == 3) { seg.set(id, -INF); } else if (e[0] == 4) { int l = queries[id][0]; int r = queries[id][1]; ans[id] = max(ans[id], seg.qmax(1, l, r)); } } } }; solve(); reverse(a.begin(), a.end()); reverse(b.begin(), b.end()); reverse(h.begin(), h.end()); for (int i = 0; i < q; i++) { queries[i][0] = n - 1 - queries[i][0]; queries[i][1] = n - 1 - queries[i][1]; swap(queries[i][0], queries[i][1]); } solve(); for (int i = 0; i < q; i++) cout << ans[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...