Submission #1299659

#TimeUsernameProblemLanguageResultExecution timeMemory
1299659chaitanyamehtaFuel Station (NOI20_fuelstation)C++20
100 / 100
348 ms50920 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const ll INFLL = (1LL<<60); struct Station { ll x; ll a; ll b; int idx; }; // comparator functions (no lambdas) bool cmpByX(const Station &s1, const Station &s2) { return s1.x < s2.x; } bool cmpByBDesc(const Station &s1, const Station &s2) { return s1.b > s2.b; } // Segment tree that supports range add and query global max struct SegTree { int n; // number of leaves (size) vector<ll> mx; // max values vector<ll> lazy; // lazy addition SegTree() : n(0) {} SegTree(int sz) { init(sz); } void init(int sz) { n = 1; while (n < sz) n <<= 1; mx.assign(2*n, -INFLL); lazy.assign(2*n, 0); } void build(const vector<ll> &arr) { // arr size <= n int m = (int)arr.size(); for (int i = 0; i < m; ++i) mx[n + i] = arr[i]; for (int i = m; i < n; ++i) mx[n + i] = -INFLL; for (int i = n - 1; i >= 1; --i) mx[i] = max(mx[2*i], mx[2*i+1]); } void apply(int node, ll val) { mx[node] += val; lazy[node] += val; } void push(int node) { if (lazy[node] != 0) { apply(2*node, lazy[node]); apply(2*node+1, lazy[node]); lazy[node] = 0; } } void pull(int node) { mx[node] = max(mx[2*node], mx[2*node+1]); } // add 'val' to range [l, r] inclusive void range_add(int l, int r, ll val) { if (l > r) return; range_add_rec(l, r, val, 1, 0, n-1); } void range_add_rec(int l, int r, ll val, int node, int nl, int nr) { if (r < nl || nr < l) return; if (l <= nl && nr <= r) { apply(node, val); return; } push(node); int mid = (nl + nr) >> 1; range_add_rec(l, r, val, 2*node, nl, mid); range_add_rec(l, r, val, 2*node+1, mid+1, nr); pull(node); } ll query_max() { return mx[1]; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; ll D; if (!(cin >> N >> D)) return 0; vector<Station> st(N); for (int i = 0; i < N; ++i) { st[i].idx = i; cin >> st[i].x >> st[i].a >> st[i].b; } // sort stations by position x vector<Station> byPos = st; sort(byPos.begin(), byPos.end(), cmpByX); // build positions array: station positions then destination int m = N + 1; vector<ll> xs(m); for (int i = 0; i < N; ++i) xs[i] = byPos[i].x; xs[N] = D; // map original station index -> position index vector<int> posIndex(N); for (int i = 0; i < N; ++i) posIndex[ byPos[i].idx ] = i; // prepare vector of stations sorted by B descending vector<Station> byB = st; sort(byB.begin(), byB.end(), cmpByBDesc); // initial v[i] = x_i (pref = 0) vector<ll> v(m); for (int i = 0; i < m; ++i) v[i] = xs[i]; SegTree seg(m); seg.init(m); seg.build(v); ll ans = D; // empty-set candidate: no stations usable => need D fuel int idx = 0; while (idx < N) { ll curB = byB[idx].b; // process group of stations with the same B value int j = idx; while (j < N && byB[j].b == curB) { int origIdx = byB[j].idx; int p = posIndex[origIdx]; // position index in xs: 0..N-1 for stations ll A = byB[j].a; // when this station becomes usable, it reduces required fuel // for all checkpoints strictly after its position (i > p). seg.range_add(p+1, m-1, -A); ++j; } idx = j; ll g = seg.query_max(); if (g < 0) g = 0; // starting fuel can't be negative; 0 means no initial fuel required if (g <= curB) { if (g < ans) ans = g; } } cout << ans << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...