Submission #1256306

#TimeUsernameProblemLanguageResultExecution timeMemory
1256306biankShortcut (IOI16_shortcut)C++20
100 / 100
1244 ms39528 KiB
#include <bits/stdc++.h>

using namespace std;

#define forsn(i, s, n) for (int i = int(s); i < int(n); i++)
#define forn(i, n) forsn(i, 0, n)
#define dforsn(i, s, n) for (int i = int(n) - 1; i >= int(s); i--)
#define dforn(i, n) dforsn(i, 0, n)

#define sz(x) int(x.size())
#define all(x) begin(x), end(x)

using ii = pair<int, int>;
using vi = vector<int>;
using ll = long long;
using vll = vector<ll>;
using pll = pair<ll, ll>;

#define fst first
#define snd second

#define pb push_back
#define eb emplace_back

const ll INF = 1e18;

const int MAX_N = 1e6 + 9;

ll x[MAX_N], d[MAX_N];
int n, c;

int order[2][MAX_N];

ll val(int i, int t) {
    if (i == -1) return -INF;
    if (t == 0) return x[i] + d[i];
    if (t == 1) return -x[i] + d[i];
    assert(false);
}

pll intersection(pll a, pll b) {
    return pll{max(a.fst, b.fst), min(a.snd, b.snd)};
}

void upd(ii &a, int i, int t) {
    if (val(i, t) > val(a.fst, t)) {
        a.snd = a.fst;
        a.fst = i;
    } else if (val(i, t) > val(a.snd, t)) {
        a.snd = i;
    }
}

bool check(ll R) {
    int idx = n - 1;
    ii best[2] = {{-1, -1}, {-1, -1}};
    pll rangeSum = {-INF, INF}, rangeDiff = {-INF, INF};
    auto consider = [&](int i, int j) {
        if (i > j) swap(i, j);
        if (i == -1) return;
        ll v = R - c - d[i] - d[j];
        rangeSum = intersection(rangeSum, make_pair(x[i] + x[j] - v, 
                                                    x[i] + x[j] + v));
        rangeDiff = intersection(rangeDiff, make_pair(x[j] - x[i] - v,
                                                      x[j] - x[i] + v));
    };
    forn(i, n) {
        while (idx >= 0 && val(order[1][idx], 1) > R - val(order[0][i], 0)) {
            forn(j, 2) upd(best[j], order[1][idx], j);
            idx--;
        }
        forn(j, 2) {
            int k = best[j].fst;
            if (k == order[0][i]) k = best[j].snd;
            consider(order[0][i], k); 
        }
    }
    if (rangeDiff.fst > rangeDiff.snd || rangeSum.fst > rangeSum.snd) return false;
    int j = n, k = 0;
    forn(i, n) {
        while (j > 0 && x[i] + x[j - 1] >= rangeSum.fst) j--;
        while (k < n && x[k] - x[i] < rangeDiff.fst) k++;
        int candidate = max({j, k, i + 1});
        if (candidate < n && rangeDiff.fst <= x[candidate] - x[i] && x[candidate] - x[i] <= rangeDiff.snd &&
            rangeSum.fst <= x[i] + x[candidate] && x[i] + x[candidate] <= rangeSum.snd) {
            return true;
        }
    }
    return false;
}

ll find_shortcut(int _n, vi l, vi _d, int _c) {
    n = _n, c = _c;
    x[0] = 0LL;
    forn(i, n - 1) x[i + 1] = x[i] + l[i];
    forn(i, n) d[i] = _d[i];
    forn(j, 2) forn(i, n) order[j][i] = i;
    forn(j, 2) sort(order[j], order[j] + n, [&](const int &lhs, const int &rhs) {
        return val(lhs, j) < val(rhs, j);
    });
    ll lo = 0, hi = x[n - 1] + int(2e9 + 20);
    while (hi - lo > 1) {
        ll mid = (lo + hi) / 2;
        if (check(mid)) hi = mid;
        else lo = mid;
    }
    return hi;
}

Compilation message (stderr)

shortcut.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
shortcut_c.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
#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...