제출 #613709

#제출 시각아이디문제언어결과실행 시간메모리
613709tengiz05Two Antennas (JOI19_antennas)C++17
100 / 100
1297 ms45216 KiB
#include <bits/stdc++.h> using i64 = long long; using namespace std; constexpr int N = 2E5; constexpr i64 inf = 1E18; struct Info { i64 max; i64 allmax; Info() : max(-2 * inf), allmax(-2 * inf) {} }; Info operator+(const Info &a, const Info &b) { Info c; c.max = max(a.max, b.max); c.allmax = max(a.allmax, b.allmax); return c; } struct Tag { i64 x; i64 mx; Tag(i64 x = 0) : x(x), mx(max(0LL, x)) {} }; void apply(Tag &a, const Tag &b) { a.mx = max(a.mx, a.x + b.mx); a.x += b.x; } void apply(Info &a, const Tag &b) { a.allmax = max({a.allmax, a.max + b.mx}); a.max += b.x; } template<class Info, class Tag, class Merge = std::plus<Info>> struct LazySegmentTree { const int n; const Merge merge; std::vector<Info> info; std::vector<Tag> tag; LazySegmentTree(int n) : n(n), merge(Merge()), info(4 << std::__lg(n)), tag(4 << std::__lg(n)) {} LazySegmentTree(std::vector<Info> init) : LazySegmentTree(init.size()) { std::function<void(int, int, int)> build = [&](int p, int l, int r) { if (r - l == 1) { info[p] = init[l]; return; } int m = (l + r) / 2; build(2 * p, l, m); build(2 * p + 1, m, r); pull(p); }; build(1, 0, n); } void reconstruct() { info.assign(4 << std::__lg(n), Info()); tag.assign(4 << std::__lg(n), Tag()); } void pull(int p) { info[p] = merge(info[2 * p], info[2 * p + 1]); } void apply(int p, const Tag &v) { ::apply(info[p], v); ::apply(tag[p], v); } void push(int p) { apply(2 * p, tag[p]); apply(2 * p + 1, tag[p]); tag[p] = Tag(); } void modify(int p, int l, int r, int x, Info v) { if (r - l == 1) { info[p] = v; return; } int m = (l + r) / 2; push(p); if (x < m) { modify(2 * p, l, m, x, v); } else { modify(2 * p + 1, m, r, x, v); } pull(p); } void modify(int x, Info v) { modify(1, 0, n, x, v); } Info rangeQuery(int p, int l, int r, int x, int y) { if (l >= y || r <= x) { return Info(); } if (l >= x && r <= y) { return info[p]; } int m = (l + r) / 2; push(p); return merge(rangeQuery(2 * p, l, m, x, y), rangeQuery(2 * p + 1, m, r, x, y)); } Info rangeQuery(int l, int r) { return rangeQuery(1, 0, n, l, r); } void rangeApply(int p, int l, int r, int x, int y, const Tag &v) { if (l >= y || r <= x) { return; } if (l >= x && r <= y) { apply(p, v); return; } int m = (l + r) / 2; push(p); rangeApply(2 * p, l, m, x, y, v); rangeApply(2 * p + 1, m, r, x, y, v); pull(p); } void rangeApply(int l, int r, const Tag &v) { return rangeApply(1, 0, n, l, r, v); } }; LazySegmentTree<Info, Tag> s(N); i64 A[N], historyMax[N]; void update(int p, i64 x) { auto old = s.rangeQuery(p, p + 1); s.rangeApply(p, p + 1, x - old.max); } void add(int l, int r, i64 x) { s.rangeApply(l, r, x); } int query(int l, int r) { return max(-1LL, s.rangeQuery(l, r).allmax); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); for (int i = 0; i < N; i++) { A[i] = -2 * inf; historyMax[i] = -1; } 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]; } vector<array<int, 3>> g; for (int i = 0; i < n; i++) { g.push_back({i + a[i], 1, i}); g.push_back({i + b[i] + 1, -1, i}); } sort(g.begin(), g.end()); int q; cin >> q; vector<vector<array<int, 2>>> Q(n); vector<int> ans(q); for (int i = 0; i < q; i++) { int l, r; cin >> l >> r; l--; r--; Q[r].push_back({l, i}); } int k = 0; for (int i = 0; i < n; i++) { while (k < int(g.size()) && g[k][0] == i) { int p = g[k][2]; if (g[k][1] == 1) { update(p, -inf + h[p]); } else { update(p, -2 * inf); } k++; } int L = max(0, i - b[i]); int R = max(0, i - a[i] + 1); add(L, R, -h[i]); add(L, R, inf); for (auto [l, id] : Q[i]) { ans[id] = query(l, i + 1); } add(L, R, -inf); add(L, R, h[i]); } for (int i = 0; i < N; i++) { A[i] = -2 * inf; historyMax[i] = -1; } k = 0; s.reconstruct(); for (int i = 0; i < n; i++) { while (k < int(g.size()) && g[k][0] == i) { int p = g[k][2]; if (g[k][1] == 1) { update(p, -inf + -h[p]); } else { update(p, -2 * inf); } k++; } int L = max(0, i - b[i]); int R = max(0, i - a[i] + 1); add(L, R, h[i]); add(L, R, inf); for (auto [l, id] : Q[i]) { ans[id] = max(ans[id], query(l, i + 1)); } add(L, R, -inf); add(L, R, -h[i]); } 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...