Submission #423828

#TimeUsernameProblemLanguageResultExecution timeMemory
423828KoDShortcut (IOI16_shortcut)C++17
0 / 100
0 ms204 KiB
#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()); Vec<ll> base1(n), base2(n); Vec<int> idx(n), 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] - x[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); std::sort(ord.begin(), ord.end(), [&](const int i, const int j) { return x[i] + d[i] > x[j] + d[j]; }); const auto check = [&](const ll threshold) -> bool { ll sum_min = -INF, sum_max = INF; ll dif_min = -INF, dif_max = INF; int pos = 0; for (const int i: ord) { while (pos < n and cmp[pos] <= threshold - (x[i] + d[i])) pos += 1; const ll a = [&] { if (idx[i] < pos) return min1.fold(pos, n); else return std::min(min1.fold(pos, idx[i]), min1.fold(idx[i] + 1, n)); }(); const ll b = [&] { if (idx[i] < pos) return min1.fold(pos, n); else return std::min(min1.fold(pos, idx[i]), min1.fold(idx[i] + 1, 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 = 1000000000ll * (999999ll + 2ll), ng = std::max(0, *std::max_element(d.begin(), d.end()) - 1); while (ok - ng > 1) { const auto 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...