제출 #1329809

#제출 시각아이디문제언어결과실행 시간메모리
1329809edoFuel Station (NOI20_fuelstation)C++20
100 / 100
301 ms43004 KiB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

struct Station {
    int x, a, b, id;
};
struct SegmentTree {
    int n;
    vector<ll> tree, lazy;

    SegmentTree(const vector<ll>& base) {
        n = base.size();
        tree.assign(4 * n, 0);
        lazy.assign(4 * n, 0);
        build(1, 0, n - 1, base);
    }

    void build(int node, int start, int end, const vector<ll>& base) {
        if (start == end) {
            tree[node] = base[start];
            return;
        }
        int mid = (start + end) / 2;
        build(2 * node, start, mid, base);
        build(2 * node + 1, mid + 1, end, base);
        tree[node] = min(tree[2 * node], tree[2 * node + 1]);
    }

    void push(int node) {
        if (lazy[node] != 0) {
            tree[2 * node] += lazy[node];
            lazy[2 * node] += lazy[node];
            tree[2 * node + 1] += lazy[node];
            lazy[2 * node + 1] += lazy[node];
            lazy[node] = 0;
        }
    }

    void update(int node, int start, int end, int l, int r, ll val) {
        if (start > end || start > r || end < l) return;
        if (start >= l && end <= r) {
            tree[node] += val;
            lazy[node] += val;
            return;
        }
        push(node);
        int mid = (start + end) / 2;
        update(2 * node, start, mid, l, r, val);
        update(2 * node + 1, mid + 1, end, l, r, val);
        tree[node] = min(tree[2 * node], tree[2 * node + 1]);
    }

    ll query_all() { return tree[1]; }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    ll d;
    cin >> n >> d;

    vector<Station> X(n);
    vector<pair<ll, int>> coords;

    for(int i = 0; i < n; i++) {
        cin >> X[i].x >> X[i].a >> X[i].b;
        X[i].id = i;
        coords.push_back({X[i].x, i});
    }

    coords.push_back({d, n});
    sort(coords.begin(), coords.end());

    vector<int> mpos(n + 1);
    int cnt = n;
    for(int i = n; ~i; i--) {
        if (i < n && coords[i].first != coords[i + 1].first) {
            cnt = i + 1;
        }
        mpos[coords[i].second] = cnt;
    }

    vector<tuple<ll, ll, int>> b;
    for (int i = 0; i < n; i++) {
        b.emplace_back(X[i].b, X[i].a, mpos[i]);
    }
    b.emplace_back(1e12, 0, mpos[n]);
    sort(b.begin(), b.end());

    vector<ll> base(n + 1);
    for(int i = 0; i <= n; i++) 
        base[i] = -coords[i].first;

    SegmentTree st(base);

    for (int i = 0; i < n; i++) 
        st.update(1, 0, n, get<2>(b[i]), n, get<1>(b[i]));

    ll ans = d;
    int ptr = 0;

    for(int i = 0; i <= n; i++) {
        ll curr = get<0>(b[i]);
        ll prev = (i == 0) ? 0 : get<0>(b[i - 1]);

        st.update(1, 0, n, 0, n, curr - prev);

        if (i < n && curr == get<0>(b[i + 1])) continue;

        while (get<0>(b[ptr]) != curr) {
            st.update(1, 0, n, get<2>(b[ptr]), n, -get<1>(b[ptr]));
            ptr++;
        }

        ll min_val = st.query_all();
        if (min_val >= 0) {
            ans = min(ans, curr - min_val);
        }
    }

    cout << ans;
    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...