제출 #1347175

#제출 시각아이디문제언어결과실행 시간메모리
1347175model_codeTeleporter 2 (JOI26_teleporter)C++20
100 / 100
1112 ms7756 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <ranges>

using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<P> vp;
typedef vector<bool> vb;
#define rep(i,n) for(ll i = 0; i < (ll)(n); i++)
#define REP(i,k,n) for(ll i = (ll)(k); i < (ll)(n); i++)
#define all(a) a.begin(), a.end()
template<class T> bool chmin(T&a, T b) {if(a > b) {a = b; return true;} return false;}
template<class T> void out(T a) {cout << a << '\n';}
const ll inf = 1001001001001001001;
struct edge {ll from, to, cost;};

int main() {
    cin.tie(0); ios::sync_with_stdio(false);
    ll n, m, K; cin >> n >> m >> K; n ++;
    vector<edge> edges(m);
    rep(i, m) {
        cin >> edges[i].from >> edges[i].to >> edges[i].cost;
    }
    ranges::sort(edges, {}, &edge::to);
    {
        ll curR = 0, cost = 0, num = 0;
        rep(i, m) {
            if(curR <= edges[i].from) {
                num ++;
                curR = edges[i].to;
            }
        }
        if(num <= K) {
            cout << 0 << '\n';
            return 0;
        }
    }
    ll ok = inf, ng = 0, ans = inf;
    vi idx(m), dif(m + 1), val(m + 1);
    rep(i, m) idx[i] = lower_bound(all(edges), edges[i].from + 1, [](edge a, ll b){return a.to < b;}) - edges.begin();
    while(ok - ng > 1) {
        ll md = (ok + ng) / 2;
        ll sum = 0;
        set<ll> S; S.insert(0);
        dif[0] = 0; val[0] = 0;
        rep(i, m) {
            val[i + 1] = val[*S.begin()] + 1;
            dif[i + 1] = dif[*S.begin()] + md - sum;
            sum += dif[i + 1];
            while(dif[i + 1] <= 0 && S.size()) {
                if(dif[i + 1] == 0 && val[*prev(S.end()) < val[i + 1]]) break;
                dif[i + 1] += dif[*prev(S.end())];
                S.erase(prev(S.end()));
            }
            S.insert(i + 1);
            auto itr = S.lower_bound(idx[i] + 1);
            dif[*S.begin()] += edges[i].cost;
            dif[*itr] -= edges[i].cost;
            while(dif[*itr] <= 0 && itr != S.begin()) {
                if(dif[*itr] == 0 && val[*prev(itr)] < val[*itr]) break;
                dif[*itr] += dif[*prev(itr)];
                S.erase(prev(itr));
            }
        }
        if(val[*S.begin()] <= K) {
            ok = md;
            ans = dif[*S.begin()] - md * K;
        }
        else ng = md;
    }
    out(ans);
}
#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...