제출 #1125586

#제출 시각아이디문제언어결과실행 시간메모리
1125586steveonalexTwo Antennas (JOI19_antennas)C++20
100 / 100
659 ms70884 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define MASK(i) (1LL << (i)) #define GETBIT(mask, i) (((mask) >> (i)) & 1) #define ALL(v) (v).begin(), (v).end() ll max(ll a, ll b){return (a > b) ? a : b;} ll min(ll a, ll b){return (a < b) ? a : b;} ll gcd(ll a, ll b){ while(a > 0 && b > 0){ if (a > b) a %= b; else b %= a; } return a + b; } ll LASTBIT(ll mask){return (mask) & (-mask);} int pop_cnt(ll mask){return __builtin_popcountll(mask);} int ctz(ll mask){return __builtin_ctzll(mask);} int logOf(ll mask){return __lg(mask);} mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);} template <class T1, class T2> bool maximize(T1 &a, T2 b){ if (a < b) {a = b; return true;} return false; } template <class T1, class T2> bool minimize(T1 &a, T2 b){ if (a > b) {a = b; return true;} return false; } template <class T> void printArr(T& container, string separator = " ", string finish = "\n"){ for(auto item: container) cout << item << separator; cout << finish; } template <class T> void remove_dup(vector<T> &a){ sort(ALL(a)); a.resize(unique(ALL(a)) - a.begin()); } const ll INF = 1e18 + 69; struct SegmentTree{ int n; vector<ll> a; SegmentTree(int _n){ n = _n; a.resize(n * 2 + 2, -INF); } void update(int i, ll v){ i += n; maximize(a[i], v); while(i > 1){ i >>= 1; a[i] = max(a[i * 2], a[i * 2 + 1]); } } ll get(int l, int r){ l += n; r += n + 1; ll ans = -INF; while(l < r){ if (l & 1) maximize(ans, a[l++]); if (r & 1) maximize(ans, a[--r]); l >>= 1; r >>= 1; } return ans; } }; struct SegmentTreeLazy{ struct Node{ ll a, b, lazy; Node(){ a = b = lazy = -INF; } }; int n; vector<Node> a; SegmentTreeLazy(int n): n(n){ a.resize(n * 4 + 4); } void apply_a(int id, pair<ll, ll> val){ a[id].a = val.first; a[id].b = val.first + val.second; } void apply_b(int id, ll val){ maximize(a[id].b, a[id].a + val); maximize(a[id].lazy, val); } void down(int id){ apply_b(id * 2, a[id].lazy); apply_b(id * 2 + 1, a[id].lazy); a[id].lazy = -INF; } Node combine(Node a, Node b){ Node c; c.a = max(a.a, b.a); c.b = max(a.b, b.b); return c; } void update_a(int i, pair<ll, ll> val, int l, int r, int id){ if (l == r){ apply_a(id, val); return; } if (a[id].lazy != -INF) down(id); int mid = (l + r) >> 1; if (i <= mid) update_a(i, val, l, mid, id * 2); else update_a(i, val, mid + 1, r, id * 2 + 1); a[id] = combine(a[id * 2], a[id * 2 + 1]); } void update_a(int i, pair<ll, ll> val){ update_a(i, val, 1, n, 1); } void update_b(int u, int v, ll val, int l, int r, int id){ if (u <= l && r <= v){ apply_b(id, val); return; } if (a[id].lazy != -INF) down(id); int mid = (l + r) >> 1; if (u <= mid) update_b(u, v, val, l, mid, id * 2); if (v > mid) update_b(u, v, val, mid + 1, r, id * 2 + 1); a[id] = combine(a[id * 2], a[id * 2 + 1]); } void update_b(int l, int r, ll val){ update_b(l, r, val, 1, n, 1); } ll get(int u, int v, int l, int r, int id){ if (u <= l && r <= v) return a[id].b; if (a[id].lazy != -INF) down(id); int mid = (l + r) >> 1; ll ans = -INF; if (u <= mid) maximize(ans, get(u, v, l, mid, id * 2)); if (v > mid) maximize(ans, get(u, v, mid + 1, r, id * 2 + 1)); return ans; } ll get(int u, int v){return get(u, v, 1, n, 1);} }; void solve(){ int n; cin >> n; vector<array<ll, 3>> a(n+1); for(int i =1 ; i<=n; ++i) cin >> a[i][0] >> a[i][1] >> a[i][2]; vector<vector<int>> range_enter(n+1), range_exit(n+1); for(int i = 1; i<=n; ++i) { int l = i + a[i][1], r = i + a[i][2]; minimize(r, n); if (l > r) continue; range_enter[l].push_back(i); range_exit[r].push_back(i); } int q; cin >> q; vector<vector<pair<int, int>>> query(n+1); vector<ll> ans(q, -INF); for(int i = 0; i < q; ++i){ int l, r; cin >> l >> r; query[r].push_back({l, i}); } SegmentTree st(n); SegmentTreeLazy satan(n), angel(n); for(int i = 1; i<=n; ++i) { for(int j: range_enter[i]){ satan.update_a(j, {-a[j][0], -INF}); angel.update_a(j, {a[j][0], -INF}); } int l = i - a[i][2], r = i - a[i][1]; maximize(l, 1); if (l <= r){ satan.update_b(l, r, a[i][0]); angel.update_b(l, r, -a[i][0]); } for(pair<int, int> j: query[i]){ maximize(ans[j.second], st.get(j.first, i)); maximize(ans[j.second], satan.get(j.first, i)); maximize(ans[j.second], angel.get(j.first, i)); maximize(ans[j.second], -1); } for(int j: range_exit[i]){ st.update(j, satan.get(j, j)); st.update(j, angel.get(j, j)); satan.update_a(j, {-INF, -INF}); angel.update_a(j, {-INF, -INF}); } } printArr(ans); } int main(void){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); clock_t start = clock(); solve(); cerr << "Time elapsed: " << clock() - start << "ms!\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...