제출 #1328826

#제출 시각아이디문제언어결과실행 시간메모리
1328826vuton101982추월 (IOI23_overtaking)C++20
100 / 100
1467 ms144456 KiB
#include "overtaking.h"
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

// Each element: [start, end], ordered by start then end.
using Seg = array<ll, 2>;

static ll gX, gL;
static set<Seg> mp;                 // global envelope after all stations

void init(int L, int N, std::vector<long long> T, std::vector<int> W,
          int X, int M, std::vector<int> S) {
    gX = X;
    gL = L;
    mp.clear();

    // traj[j] stores per-segment constraints for reduced time across segment j -> j+1
    // represented as pairs (start_reduced_at_station_j, end_reduced_at_station_{j+1})
    vector< set<Seg> > traj(max(0, M - 1));

    // Only buses slower than reserve (W[i] > X) can block it.
    // Let w = W[i] - X, then reduced time increases by w * distance.
    vector<Seg> buses;
    buses.reserve(N);
    for (int i = 0; i < N; i++) {
        if ((ll)W[i] > gX) {
            buses.push_back({(ll)W[i] - gX, T[i]}); // [w, start_time_at_airport]
        }
    }

    // Process buses in descending w (slowest-first in reduced-slope sense).
    sort(buses.begin(), buses.end());
    reverse(buses.begin(), buses.end());

    for (auto &bt : buses) {
        ll w = bt[0];
        ll cur = bt[1]; // reduced time at station 0 (since S[0]=0)

        for (int j = 0; j < M - 1; j++) {
            ll d = (ll)S[j + 1] - S[j];
            ll nxt = cur + d * w; // expected reduced arrival if not blocked by even slower buses

            // If there exists an already-processed (slower) bus with start < cur,
            // then this bus's reduced arrival becomes at least that bus's reduced arrival.
            auto it = traj[j].lower_bound({cur, (ll)-4e18});
            if (it != traj[j].begin()) {
                nxt = max(nxt, (*prev(it))[1]);
            }

            traj[j].insert({cur, nxt});
            cur = nxt;
        }
    }

    // Merge segments from last to first into mp (overall envelope).
    // Maintain mp as an increasing-start, increasing-end envelope, pruning dominated entries.
    for (int j = M - 2; j >= 0; j--) {
        for (auto &se : traj[j]) {
            ll s = se[0], e = se[1];

            // Compose with already-built envelope on the suffix (j+1..end):
            // if reduced time after this segment is e, it may be further pushed up by mp.
            auto it = mp.lower_bound({e, (ll)-4e18});
            if (it != mp.begin()) e = max(e, (*prev(it))[1]);

            // Insert (s -> e) into mp, removing dominated intervals.
            it = mp.lower_bound({s, (ll)-4e18});
            while (it != mp.end() && (*it)[1] <= e) {
                it = mp.erase(it);
            }
            mp.insert({s, e});
        }
    }
}

long long arrival_time(long long Y) {
    // Work in reduced time at station 0: R0 = Y.
    // Push it up using mp envelope.
    auto it = mp.lower_bound({Y, (ll)-4e18});
    if (it != mp.begin()) {
        Y = max(Y, (*prev(it))[1]);
    }
    // Convert reduced time back to real time at hotel:
    // t = R + X * L
    return Y + gX * gL;
}
#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...