답안 #423800

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
423800 2021-06-11T12:55:12 Z KoD Shortcut (IOI16_shortcut) C++17
0 / 100
0 ms 204 KB
#include <bits/stdc++.h>
#include "shortcut.h"
 
template <class T>
using Vec = std::vector<T>;
using ll = long long;
 
constexpr ll INF = std::numeric_limits<ll>::max() / 2;
 
template <class T> void setmin(T& lhs, const T& rhs) {
    if (lhs > rhs) {
        lhs = rhs;
    }
}
 
template <class T> void setmax(T& lhs, const T& rhs) {
    if (lhs < rhs) {
        lhs = rhs;
    }
}
 
struct RMQ {
    Vec<Vec<ll>> table;
    RMQ(const Vec<ll>& vec) {
        const int n = (int) vec.size();
        const int h = 32 - __builtin_clz(n);
        table.resize(h, Vec<ll>(n));
        table[0] = vec;
        for (int k = 0; k < h - 1; ++k) {
            for (int i = 0; i < n; ++i) {
                table[k + 1][i] = table[k][i];
                if (i + (1 << k) < n) {
                    table[k + 1][i] = std::min(table[k + 1][i], table[k][i + (1 << k)]);
                }
            }
        }
    }
    ll fold(const int l, const int r) {
        if (l >= r) return INF;
        const int h = 31 - __builtin_clz(r - l);
        return std::min(table[h][l], table[h][r - (1 << h)]);
    }
};
 
ll find_shortcut(int n, Vec<int> l, Vec<int> d, int c) {
    Vec<ll> x(n);
    for (int i = 1; i < n; ++i) {
        x[i] = x[i - 1] + l[i - 1];
    }
    Vec<ll> cmp(n);
    for (int i = 0; i < n; ++i) {
        cmp[i] = d[i] - x[i];
    }
    std::sort(cmp.begin(), cmp.end());
    cmp.erase(std::unique(cmp.begin(), cmp.end()), cmp.end());
    Vec<ll> base1(n), base2(n);
    Vec<int> idx(n);
    Vec<int> ord(n);
    std::iota(ord.begin(), ord.end(), 0);
    std::sort(ord.begin(), ord.end(), [&](const int i, const int j) {
        return d[i] - x[i] < d[j] - d[j];
    });
    for (int i = 0; i < n; ++i) {
        idx[ord[i]] = i;
    }
    for (int i = 0; i < n; ++i) {
        base1[idx[i]] = x[i] - d[i];
        base2[idx[i]] = -(x[i] + d[i]);
    }
    RMQ min1(base1), min2(base2);
    const auto check = [&](const ll threshold) -> bool {
        ll sum_min = -INF, sum_max = INF;
        ll dif_min = -INF, dif_max = INF;
        for (int i = 0; i < n; ++i) {
            const int pos = std::upper_bound(cmp.begin(), cmp.end(), threshold - (x[i] + d[i])) - cmp.begin();
            const ll a = std::min(min1.fold(pos, std::max(pos, idx[i])), min1.fold(std::max(idx[i] + 1, pos), n));
            const ll b = std::min(min2.fold(pos, std::max(pos, idx[i])), min2.fold(std::max(idx[i] + 1, pos), n));
            if (a != std::numeric_limits<ll>::max()) {
                setmin(sum_max, a + (x[i] - d[i]) + threshold - c);
                setmax(sum_min, -b + (x[i] + d[i]) + c - threshold);
                setmin(dif_max, b + (x[i] - d[i]) + threshold - c);
                setmax(dif_min, -a + (x[i] + d[i]) + c - threshold);
            }
        } 
        if (sum_min > sum_max or dif_min > dif_max)  {
            return false;
        }
        int s = n, t = 0, u = n - 1, v = 0;
        for (int i = 0; i < n; ++i) {
            while (s > 0 and x[s - 1] >= sum_min - x[i]) s -= 1;
            while (t < n and x[t] < dif_min + x[i]) t += 1;
            while (u >= 0 and x[u] > sum_max - x[i]) u -= 1;
            while (v + 1 < n and x[v + 1] <= dif_max + x[i]) v += 1;
            if (std::max({s, t, i + 1}) <= std::min(u, v)) {
                return true;
            }
        }
        return false;
    };
    ll ok = INF, ng = 0;
    while (ok - ng > 1) {
        const auto md = (ok + ng) / 2;
        (check(md) ? ok : ng) = md;
    }
    return ok;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB n = 4, 80 is a correct answer
2 Incorrect 0 ms 204 KB n = 9, incorrect answer: jury 110 vs contestant 130
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB n = 4, 80 is a correct answer
2 Incorrect 0 ms 204 KB n = 9, incorrect answer: jury 110 vs contestant 130
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB n = 4, 80 is a correct answer
2 Incorrect 0 ms 204 KB n = 9, incorrect answer: jury 110 vs contestant 130
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB n = 4, 80 is a correct answer
2 Incorrect 0 ms 204 KB n = 9, incorrect answer: jury 110 vs contestant 130
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB n = 4, 80 is a correct answer
2 Incorrect 0 ms 204 KB n = 9, incorrect answer: jury 110 vs contestant 130
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB n = 4, 80 is a correct answer
2 Incorrect 0 ms 204 KB n = 9, incorrect answer: jury 110 vs contestant 130
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB n = 4, 80 is a correct answer
2 Incorrect 0 ms 204 KB n = 9, incorrect answer: jury 110 vs contestant 130
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB n = 4, 80 is a correct answer
2 Incorrect 0 ms 204 KB n = 9, incorrect answer: jury 110 vs contestant 130
3 Halted 0 ms 0 KB -