Submission #1085683

#TimeUsernameProblemLanguageResultExecution timeMemory
1085683belgianbotOvertaking (IOI23_overtaking)C++17
100 / 100
3284 ms106824 KiB
#include "overtaking.h"
#include <bits/stdc++.h>
#define int long long
#define fi first 
#define se second 
using namespace std;

vector<signed> W, S;
vector<long long> T;
vector<vector<int>> dp;
vector<vector<vector<int>>> arr;
int L, N, X, M;
void init(signed LL, signed NN, std::vector<long long> TT, std::vector<signed> WW, signed XX, signed MM, std::vector<signed> SS)
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    L = LL; N = NN; X = XX; M = MM; S = SS;
    int n = N;
    for (int i = 0; i < N; i++) {
        if (WW[i] <= X) {
            n--;
            continue;
        }
        T.push_back(TT[i]);
        W.push_back(WW[i]);
    }
    N = n;
    dp.resize(M, vector<int>(N));
    arr.resize(M);
    vector<vector<int>> bus(N, vector<int> (M));

    for (int i = 0; i < N; i++) {
        arr[0].push_back({T[i], W[i], i});
        bus[i][0] = T[i];
    }

    sort(arr[0].begin(), arr[0].end());

    for (int i = 1; i < M; i++) {
        int last = 0;
        for (int j = 0; j < N; j++) {
            int expected = arr[i - 1][j][0] + arr[i - 1][j][1] * (S[i] - S[i - 1]);
            if (expected < last) arr[i].push_back({last, arr[i - 1][j][1], arr[i - 1][j][2]});
            else {
                last = expected;
                arr[i].push_back({expected, arr[i - 1][j][1], arr[i-1][j][2]});
            }
            bus[arr[i-1][j][2]][i] = last;
        }
        sort(arr[i].begin(), arr[i].end());
    }

    for (int i = 0; i < N; i++) dp[M - 1][i] = bus[i][M - 1];
    for (int i = M - 2; i > 0; i--) {
        for (int j = 0; j < N; j++) {
            
            int next = bus[j][i];
            int nb = arr[i].end() - upper_bound(arr[i].begin(), arr[i].end(), vector<int>({next, -1, -1}));

            int l = i, r = M - 1;
            while (l <= r) {
                int mid = l + (r - l) / 2;

                int after = arr[mid].end() - upper_bound(arr[mid].begin(), arr[mid].end(), vector<int>({next + X * (S[mid] - S[i]), -1, -1}));
                if (after > nb) r = mid - 1;
                else l = mid + 1;
            }
            
            if (l == M) dp[i][j] = next + X * (S[M - 1] - S[i]);
            else dp[i][j] = dp[l][arr[l][N - nb - 1][2]];
        }
    }
    return;
}

long long arrival_time(long long Y)
{
    int l = 1, r = M - 1;
    int ans = -1;
    int nb = arr[0].end() - upper_bound(arr[0].begin(), arr[0].end(), vector<int>({Y, -1, -1}));
    while (l <= r) {
        int mid = l + (r - l) / 2;

        int after = arr[mid].end() - upper_bound(arr[mid].begin(), arr[mid].end(), vector<int>({X * S[mid] + Y, -1, -1}));
        if (after > nb) {
            ans = mid;
            r = mid - 1;
        }
        else l = mid + 1;
    }
    if (ans == -1) return S[M - 1] * X + Y;
    else return dp[ans][arr[ans][N - nb - 1][2]];
}
#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...