Submission #369779

#TimeUsernameProblemLanguageResultExecution timeMemory
369779KoDShortcut (IOI16_shortcut)C++17
38 / 100
2098 ms748 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(); struct SlideMax { struct Node { const ll val, max; Node(const ll v, const ll m): val(v), max(m) { } }; std::stack<Node> left, right; SlideMax(): left(), right() {} void push(const ll value) { right.emplace(value, std::max(right.empty() ? -INF : right.top().max, value)); } void pop() { if (left.empty()) { while (!right.empty()) { const auto node = right.top(); right.pop(); left.emplace(node.val, std::max(left.empty() ? -INF : left.top().max, node.val)); } } left.pop(); } ll fold() const { return std::max(left.empty() ? -INF : left.top().max, right.empty() ? -INF : right.top().max); } }; ll solve(const int n, const Vec<ll> &weight, const Vec<ll> &dist) { const auto sum = std::accumulate(dist.begin(), dist.end(), (ll) 0); Vec<ll> cum(2 * n); for (int i = 1; i < 2 * n; ++i) { cum[i] = cum[i - 1] + dist[(i - 1) % n]; } SlideMax max; int r = 0; ll ret = -INF; for (int i = 0; i < n; ++i) { if (r == i) { r = i + 1; } else { max.pop(); } while ((cum[r] - cum[i]) * 2 <= sum) { max.push(cum[r] + weight[r % n]); r += 1; } ret = std::max(ret, max.fold() - cum[i] + weight[i]); } // for (const auto x: weight) { // std::cerr << x << ' '; // } // std::cerr << '\n'; // for (const auto x: dist) { // std::cerr << x << ' '; // } // std::cerr << '\n'; // std::cerr << ret << '\n'; return ret; } ll find_shortcut(int n, Vec<int> l, Vec<int> d, int c) { Vec<ll> left(n), lmax(n); left[0] = d[0]; for (int i = 1; i < n; ++i) { left[i] = std::max<ll>(left[i - 1] + l[i - 1], d[i]); lmax[i] = std::max<ll>(lmax[i - 1], left[i - 1] + l[i - 1] + d[i]); } Vec<ll> right(n), rmax(n); right[n - 1] = d[n - 1]; for (int i = n - 2; i >= 0; --i) { right[i] = std::max<ll>(right[i + 1] + l[i], d[i]); rmax[i] = std::max<ll>(rmax[i + 1], right[i + 1] + l[i] + d[i]); } // for (const auto x: left) { // std::cerr << x << ' '; // } // std::cerr << '\n'; ll ans = INF; for (int i = 0; i < n - 1; ++i) { Vec<ll> weight, dist; weight.push_back(left[i]); dist.push_back(l[i]); for (int j = i + 1; j < n; ++j) { weight.push_back(right[j]); dist.push_back(c); ans = std::min(ans, std::max({ lmax[i], rmax[j], solve(j - i + 1, weight, dist) })); if (j + 1 == n) { break; } weight.back() = d[j]; dist.back() = l[j]; } } return ans; }
#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...