제출 #1176328

#제출 시각아이디문제언어결과실행 시간메모리
1176328nguyenkhangninh99Fuel Station (NOI20_fuelstation)C++17
100 / 100
1615 ms61712 KiB

#include<bits/stdc++.h>

using namespace std;

#define int long long

const int maxn = 3e5 + 5;

struct ttt{
    int x, a, b;
} tram[maxn];

bool cmp(ttt c1, ttt c2){
    return c1.x < c2.x;
}

vector<pair<int, int>> tram2[10005];

int n, d; 
int st[4 * maxn], lazy[4 * maxn];


bool check(int mid){
    int fuel = mid;
    for(int i = 1; i <= n; i++){
        if(fuel >= tram[i].x) fuel += tram[i].a;
        else return false;
    }
    return true;
}

bool check2(int f){
    int fuel = f;
    for(int i = 1; i <= d; i++){
        if(fuel < i) return false;
        int l = 0, r = tram2[i].size() - 1, ans = -1;
        while(l <= r){
            int mid = (l + r) / 2;
            if(tram2[i][mid].first >= f){
                ans = mid;
                l = mid + 1;
            }
            else r = mid - 1;
        }
        if(ans != -1) fuel += tram2[i][ans].second;
    }
    return true;
}

int check3(int f){
    int fuel = f, ans = 1e9;
    for(int i = 1; i <= n; i++){
        if(fuel >= tram[i].x){
            ans = min(ans, fuel - tram[i].x);
            if(f <= tram[i].b) fuel += tram[i].a;
        }
        else return -1;
        
    }
    return ans;
}


void fix(int id, int l, int r)
{
    if (!lazy[id]) return;
    st[id] += lazy[id];
 
    if (l != r)
    {
        lazy[id*2] += lazy[id];
        lazy[id*2+1] += lazy[id];
    }
 
    lazy[id] = 0;
}
 
void update(int id, int l, int r, int u, int v, int val)
{
    fix(id, l, r);
    if (v < l || r < u) return;
    if (u <= l && r <= v)
    {
        lazy[id] += val;
        fix(id, l, r);
        return;
    }
 
    int mid = l+r>>1;
    update(id*2, l, mid, u, v, val);
    update(id*2+1, mid+1, r, u, v, val);
    st[id] = min(st[id*2], st[id*2+1]);
}
 
 
void solve(){
   cin >> n >> d;

    int mn = 1e9;
    for(int i = 1; i <= n; i++){
        cin >> tram[i].x >> tram[i].a >> tram[i].b;
        mn = min(mn, tram[i].b);
    }
    sort(tram + 1, tram + n + 1, cmp);

    if(n == 1){
        if(max(tram[1].x, d - tram[1].a) <= tram[1].b) cout << max(tram[1].x, d - tram[1].a);
        else cout << d;
    }


    else if(mn == 1e9){
        int l = 1, r = d, ans = 1;
        while(l <= r){
            int mid = (l + r) / 2;

            if(check(mid)){
                ans = mid;
                r = mid - 1;
            }
            else l = mid + 1;
        }

        cout << ans;
    }

    else if(d <= 10000){
        for(int i = 1; i <= n; i++) tram2[tram[i].x].push_back({tram[i].b, tram[i].a});
        for(int i = 1; i <= d; i++){
            sort(tram2[i].begin(), tram2[i].end(), greater<>());
            for(int j = 1; j < tram2[i].size(); j++) tram2[i][j].second += tram2[i][j - 1].second;
        }

        for(int f = 1; f <= d; f++){
            if(check2(f)){
                cout << f;
                return;
            }
        }
    }
    else if(n <= 10000){
        int ans = d;
        for(int i = 1; i <= n; i++){
            int k = check3(tram[i].b);
            if(k >= 0) ans = min(ans, tram[i].b - k);
        }
        cout << ans;
    }
    else{
        vector<int> v, ans(n + 1);

        map<int, vector<int>> mp;

        for(int i = 1; i <= n; i++){
            v.push_back(tram[i].b);
            mp[tram[i].b].push_back(i);
        }

        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
        for(int i = 1; i <= n; i++){
            update(1, 1, n, i, i, v[0] - tram[i].x);
            int l = i + 1, r = n;
            while(l <= r){
                int mid = (l + r) / 2;
                if(tram[mid].x > tram[i].x){
                    ans[i] = mid;
                    r = mid - 1;
                }
                else l = mid + 1;
            }

            if(ans[i] > 0) update(1, 1, n, ans[i], n, tram[i].a);
        }

        int kq = 1e15;
        int z = st[1];
        if(z >= 0) kq = min(kq, v[0] - z);
        for(int i = 1; i < v.size(); i++){
            update(1, 1, n, 1, n, v[i] - v[i - 1]);
            for(int y: mp[v[i - 1]]){
                if(ans[y] > 0) update(1, 1, n, ans[y], n, -tram[y].a);
            }
            z = st[1];
            if(z >= 0) kq = min(kq, v[i] - z);
        }
        
        cout << kq;
    }
}


 
signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    solve();
}

#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...