Submission #767642

#TimeUsernameProblemLanguageResultExecution timeMemory
767642minhcoolTwo Antennas (JOI19_antennas)C++17
0 / 100
331 ms74216 KiB
#define local #ifndef local #include "" #endif #include<bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; using namespace std; #define int long long #define fi first #define se second #define pb push_back #define mp make_pair typedef pair<int, int> ii; typedef pair<ii, int> iii; typedef pair<ii, ii> iiii; const int N = 4e5 + 5; const int oo = 1e18 + 7, mod = 1e9 + 7; mt19937 rng(1); int rnd(int l, int r){ int temp = rng() % (r - l + 1); return abs(temp) + l; } int n, a[N], b[N], h[N]; int cal[N]; int mini[N << 2], maxi[N << 2]; ii updates[N << 2]; int total[N << 2]; void build(int id, int l, int r){ mini[id] = oo, maxi[id] = -oo; updates[id] = {oo, -oo}; total[id] = -oo; if(l == r) return; int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); } // ins1, er1, get1 -> for calculating cal[] void ins1(int id, int l, int r, int pos){ if(l == r){ mini[id] = maxi[id] = h[pos]; return; } int mid = (l + r) >> 1; if(pos <= mid) ins1(id << 1, l, mid, pos); else ins1(id << 1 | 1, mid + 1, r, pos); mini[id] = min(mini[id << 1], mini[id << 1 | 1]); maxi[id] = max(maxi[id << 1], maxi[id << 1 | 1]); } void er1(int id, int l, int r, int pos){ if(l == r){ mini[id] = oo; maxi[id] = -oo; return; } int mid = (l + r) >> 1; if(pos <= mid) ins1(id << 1, l, mid, pos); else ins1(id << 1 | 1, mid + 1, r, pos); mini[id] = min(mini[id << 1], mini[id << 1 | 1]); maxi[id] = max(maxi[id << 1], maxi[id << 1 | 1]); } ii get1(int id, int l, int r, int L, int R){ if(l > R || r < L || l > r) return {oo, -oo}; if(l >= L && r <= R) return {mini[id], maxi[id]}; int mid = (l + r) >> 1; ii a = get1(id << 1, l, mid, L, R); ii b = get1(id << 1 | 1, mid + 1, r, L, R); return {min(a.fi, b.fi), max(a.se, b.se)}; } void lazy(int id){ int mn = updates[id].fi, mx = updates[id].se; updates[id << 1].fi = min(updates[id << 1].fi, mn); updates[id << 1 | 1].fi = min(updates[id << 1 | 1].fi, mn); updates[id << 1].se = max(updates[id << 1].se, mx); updates[id << 1 | 1].se = max(updates[id << 1 | 1].se, mx); total[id << 1] = max(total[id << 1], max(updates[id << 1].se - mini[id << 1], maxi[id << 1] - updates[id << 1].fi)); total[id << 1 | 1] = max(total[id << 1 | 1], max(updates[id << 1 | 1].se - mini[id << 1 | 1], maxi[id << 1 | 1] - updates[id << 1 | 1].fi)); updates[id] = {oo, -oo}; } void merge(int id){ total[id] = max(total[id], max(total[id << 1], total[id << 1 | 1])); mini[id] = min(mini[id << 1], mini[id << 1 | 1]); maxi[id] = max(maxi[id << 1], maxi[id << 1 | 1]); // cout << "PRINT " << id << " " << total[id] << "\n"; } void ins2(int id, int l, int r, int pos){ if(l == r){ updates[id] = {oo, -oo}; total[id] = -oo; //minni[id] = {a[pos], a[pos]}; mini[id] = maxi[id] = h[pos]; return; } lazy(id); int mid = (l + r) >> 1; if(pos <= mid) ins2(id << 1, l, mid, pos); else ins2(id << 1 | 1, mid + 1, r, pos); merge(id); } void er2(int id, int l, int r, int pos){ if(l == r){ updates[id] = {oo, -oo}; total[id] = -oo; //minni[id] = {a[pos], a[pos]}; mini[id] = oo, maxi[id] = -oo; return; } lazy(id); int mid = (l + r) >> 1; if(pos <= mid) er2(id << 1, l, mid, pos); else er2(id << 1 | 1, mid + 1, r, pos); merge(id); } void upd2(int id, int l, int r, int L, int R, int val){ if(l > R || r < L) return; if(l >= L && r <= R){ updates[id] = {min(updates[id].fi, val), max(updates[id].se, val)}; total[id] = max(total[id], max(updates[id].se - mini[id], maxi[id] - updates[id].fi)); return; } lazy(id); int mid = (l + r) >> 1; upd2(id << 1, l, mid, L, R, val); upd2(id << 1 | 1, mid + 1, r, L, R, val); merge(id); } int get2(int id, int l, int r, int L, int R){ // cout << "TRAV " << id << " " << l << " " << r << " " << mini[id] << " " << maxi[id] << " " << total[id] << "\n"; if(l > R || r < L || l > r) return -oo; if(l >= L && r <= R) return total[id]; lazy(id); int mid = (l + r) >> 1; return max(get2(id << 1, l, mid, L, R), get2(id << 1 | 1, mid + 1, r, L, R)); } // this is just for storing the ones that are done int IT2[N << 2]; void upd3(int id, int l, int r, int pos, int val){ if(l == r){ IT2[id] = val; return; } int mid = (l + r) >> 1; if(pos <= mid) upd3(id << 1, l, mid, pos, val); else upd3(id << 1 | 1, mid + 1, r, pos, val); IT2[id] = max(IT2[id << 1], IT2[id << 1 | 1]); } int get3(int id, int l, int r, int L, int R){ if(l > R || r < L || l > r) return -oo; if(l >= L && r <= R) return IT2[id]; int mid = (l + r) >> 1; return max(get3(id << 1, l, mid, L, R), get3(id << 1 | 1, mid + 1, r, L, R)); } vector<ii> upds[N]; int q, answer[N]; vector<ii> queries[N]; #ifdef local void process(){ cin >> n; for(int i = 1; i <= n; i++) cin >> h[i] >> a[i] >> b[i]; build(1, 1, n); cin >> q; for(int i = 1; i <= q; i++){ int l, r; cin >> l >> r; queries[l].pb({r, i}); } // step 1: calculate the value for i (assuming that i is at the right) for each i for(int i = 0; i <= n; i++) upds[i].clear(); for(int i = 1; i <= n; i++){ upds[i + a[i]].pb({i, 1}); upds[i + b[i] + 1].pb({i, -1}); //cout << i + a[i] << " " << i + b[i] + 1 << "\n"; } for(int i = 1; i <= n; i++){ for(auto it : upds[i]){ // cout << i << " " << it.fi << " " << it.se << "\n"; if(it.se == 1) ins1(1, 1, n, it.fi); else er1(1, 1, n, it.fi); } ii temp = get1(1, 1, n, max(1LL, i - b[i]), max(0LL, i - a[i])); //cout << max(1LL, i - b[i]) << " " << max(0LL, i - a[i]) << " " << temp.fi << " " << temp.se << "\n"; cal[i] = max(h[i] - temp.fi, temp.se - h[i]); // cout << cal[i] << "\n"; } for(int i = 1; i <= (n << 2); i++) IT2[i] = -oo; build(1, 1, n); for(int i = 0; i <= n; i++) upds[i].clear(); for(int i = 1; i <= n; i++){ upds[max(0LL, i - a[i])].pb({i, 1}); upds[max(0LL, i - b[i] - 1)].pb({i, -1}); } for(int i = n; i >= 1; i--){ for(auto it : upds[i]){ if(it.se == 1) ins2(1, 1, n, it.fi); else{ er2(1, 1, n, it.fi); upd3(1, 1, n, it.fi, cal[it.fi]); } // cout << "UPDS " << it.fi << " " << it.se << "\n"; } upd2(1, 1, n, min(i + a[i], n + 1), min(i + b[i], n), h[i]); for(auto it : queries[i]){ // cout << i << " " << it.fi << " " << get2(1, 1, n, i, it.fi) << " " << get3(1, 1, n, i, it.fi) << "\n"; answer[it.se] = max(get2(1, 1, n, i, it.fi), get3(1, 1, n, i, it.fi)); } } for(int i = 1; i <= q; i++) cout << max(answer[i], -1LL) << "\n"; } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); process(); } #endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...