Submission #718065

#TimeUsernameProblemLanguageResultExecution timeMemory
718065JohannTwo Antennas (JOI19_antennas)C++14
100 / 100
526 ms38080 KiB
#include <bits/stdc++.h> using namespace std; #define pii pair<int, int> #define tiii tuple<int, int, int> #define vi vector<int> #define vvi vector<vi> #define vb vector<bool> #define vpii vector<pii> #define vtiii vector<tiii> #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() struct item { int res = -1; int ap = INT_MIN, an = INT_MIN; // apply operation int bp = INT_MAX, bn = INT_MAX; // what is contained in the Stuff }; struct SegTree { int size; vector<item> arr; void init(vi &H) { size = 1; while (size < sz(H)) size *= 2; arr.assign(2 * size, item()); } void combine(int x) { assert(arr[x].ap == INT_MIN && arr[x].an == INT_MIN); assert(x < size); arr[x].res = max(arr[2 * x].res, arr[2 * x + 1].res); arr[x].bp = min(arr[2 * x].bp, arr[2 * x + 1].bp); arr[x].bn = min(arr[2 * x].bn, arr[2 * x + 1].bn); } void apply(int x, int ap, int an) { arr[x].ap = max(arr[x].ap, ap); arr[x].an = max(arr[x].an, an); if (arr[x].ap != INT_MIN && arr[x].bp != INT_MAX) arr[x].res = max(arr[x].res, arr[x].ap - arr[x].bp); if (arr[x].an != INT_MIN && arr[x].bn != INT_MAX) arr[x].res = max(arr[x].res, arr[x].an - arr[x].bn); } void propagate(int x) { if (x < size) apply(2 * x, arr[x].ap, arr[x].an), apply(2 * x + 1, arr[x].ap, arr[x].an); arr[x].ap = arr[x].an = INT_MIN; } void update(int i, int bp, int bn, int x, int lx, int rx) { if (rx - lx == 1) { arr[x].ap = arr[x].an = INT_MIN; arr[x].bp = bp, arr[x].bn = bn; return; } propagate(x); int m = (lx + rx) / 2; if (i < m) update(i, bp, bn, 2 * x, lx, m); else update(i, bp, bn, 2 * x + 1, m, rx); combine(x); } void update(int i, int bp, int bn) { update(i, bp, bn, 1, 0, size); } void applyA(int l, int r, int ap, int an) { applyA(l, r, ap, an, 1, 0, size); } void applyA(int l, int r, int ap, int an, int x, int lx, int rx) { if (rx <= l || r <= lx) return; if (l <= lx && rx <= r) { apply(x, ap, an); return; } propagate(x); int m = (lx + rx) / 2; applyA(l, r, ap, an, 2 * x, lx, m); applyA(l, r, ap, an, 2 * x + 1, m, rx); combine(x); } int query(int l, int r, int x, int lx, int rx) { if (rx <= l || r <= lx) return -1; if (l <= lx && rx <= r) return arr[x].res; propagate(x); int m = (lx + rx) / 2; int a = query(l, r, 2 * x, lx, m); int b = query(l, r, 2 * x + 1, m, rx); return max(a, b); } int query(int l, int r) { return query(l, r, 1, 0, size); } }; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; vi H(n), A(n), B(n); vvi toAct(n + 1); vvi toDea(n + 1); for (int i = 0; i < n; ++i) { cin >> H[i] >> A[i] >> B[i]; if (i + A[i] < n) toAct[i + A[i]].push_back(i); if (i + B[i] + 1 < n) toDea[i + B[i] + 1].push_back(i); } int q; cin >> q; vtiii Q(q); for (int i = 0, l, r; i < q; ++i) { cin >> l >> r; --l, --r; Q[i] = {l, r, i}; } sort(all(Q), [&](tiii &a, tiii &b) { return get<1>(a) > get<1>(b); }); // Niedrige Endpunkte nach hinten, dann kann man den Vektor als queue verwenden vi ans(q, -1); SegTree seg; seg.init(H); vb active(n, false); for (int i = 0; i < n; ++i) { for (int j : toAct[i]) seg.update(j, H[j], -H[j]); for (int j : toDea[i]) seg.update(j, INT_MAX, INT_MAX); seg.applyA(i - B[i], i - A[i] + 1, H[i], -H[i]); while (!Q.empty() && get<1>(Q.back()) == i) { int l, r, idx; tie(l, r, idx) = Q.back(); Q.pop_back(); ans[idx] = seg.query(l, r); } } for (int x : ans) cout << x << "\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...