Submission #536131

#TimeUsernameProblemLanguageResultExecution timeMemory
536131KoDShortcut (IOI16_shortcut)C++17
100 / 100
1599 ms92248 KiB
#include <bits/stdc++.h>
#include "shortcut.h"

using ll = long long;

constexpr ll inf = std::numeric_limits<ll>::max() / 2;

using std::vector;
using std::array;
using std::pair;
using std::tuple;

ll find_shortcut(int N, vector<int> L, vector<int> D, int C) {
    vector<ll> X(N);
    for (int i = 0; i < N - 1; ++i) {
        X[i + 1] = X[i] + L[i];
    }
    vector<int> ord(N);
    std::iota(ord.begin(), ord.end(), 0);
    std::sort(ord.begin(), ord.end(), [&](const int i, const int j) {
        return X[i] + D[i] < X[j] + D[j];
    });
    vector<pair<ll, int>> sum(N);
    vector<tuple<ll, ll, int>> dif(N + 1);
    dif[N] = {inf, inf, -1};
    for (int i = N - 1; i >= 0; --i) {
        const int k = ord[i];
        sum[i] = {X[k] + D[k], k};
        if (X[k] - D[k] < std::get<0>(dif[i + 1])) {
            dif[i] = {X[k] - D[k], std::get<0>(dif[i + 1]), k};
        } else {
            dif[i] = dif[i + 1];
            std::get<1>(dif[i]) = std::min(std::get<1>(dif[i]), X[k] - D[k]);
        }
    }
    std::sort(ord.begin(), ord.end(), [&](const int i, const int j) {
        return X[i] - D[i] < X[j] - D[j];
    });
    vector<int> lowb(N);
    const auto check = [&](const ll thres) {
        ll a = -inf, b = inf, c = -inf, d = inf;
        int upb = 0;
        for (const int i : ord) {
            while (upb < N and sum[upb].first <= thres + X[i] - D[i]) upb += 1;
            if (upb == N) continue;
            if (upb == N - 1 and sum[upb].second == i) continue;
            const ll max_sum = sum[N - 1].second == i ? sum[N - 2].first : sum[N - 1].first;
            a = std::max(a, max_sum + X[i] + D[i] + C - thres);
            c = std::max(c, max_sum - X[i] + D[i] + C - thres);
            const ll min_dif = std::get<2>(dif[upb]) == i ? std::get<1>(dif[upb]) : std::get<0>(dif[upb]);
            b = std::min(b, min_dif + X[i] - D[i] - C + thres);
            d = std::min(d, min_dif - X[i] - D[i] - C + thres);
        }
        int idx = 0;
        for (int i = N - 1; i >= 0; --i) {
            while (idx < N and X[idx] < a - X[i]) idx += 1;
            lowb[i] = idx;
        }
        idx = 0;
        for (int i = 0; i < N; ++i) {
            while (idx < N and X[idx] < c + X[i]) idx += 1;
            const int k = std::max(lowb[i], idx);
            if (k < N and X[k] <= std::min(b - X[i], d + X[i])) return true;
        }
        return false;
    };
    ll ok = inf, ng = 0;
    while (ok - ng > 1) {
        const ll md = (ok + ng) / 2;
        (check(md) ? ok : ng) = md;
    }
    return ok;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...