#include #include #include #include #include using namespace std; // Same as ragnar-ansv.cpp, but when expanding the range, instead of jumping to // the next larger value, find a value that is at least 2* as large. We can do // this, because whenever we add a value of x, we can then eat everything below // 2*x. This behaviour stacks, so e.g. [x=10, 15, 30, 50] can all be added in // one step. In fact, a next value of 110 could also be added, but that only // works when starting with at least 10, not when starting at 50, so we don't do // this. // All-nearest-larger-values: // For each position, find the first position on the left and right with a larger value. auto ansv(vector& a) { vector l(a.size(), -1), r(a.size(), a.size()); for(int i = 1; i < a.size(); ++i) { l[i] = i - 1; while(l[i] >= 0 && 2 * a[i] >= a[l[i]]) l[i] = l[l[i]]; } for(int i = a.size() - 2; i >= 0; --i) { r[i] = i + 1; while(r[i] < a.size() && 2 * a[i] >= a[r[i]]) r[i] = r[r[i]]; } return pair(l, r); } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector v(n), V; for(auto& x : v) cin >> x; v.reserve(4 * n); for(auto x : v) v.push_back(x); for(auto x : v) v.push_back(x); // prefix sums exclusive_scan(begin(v), end(v), back_inserter(V), 0ll); auto [L, R] = ansv(v); long long ans = 1e18; for(int i = n; i < 2 * n; ++i) { if(v[i - 1] < v[i] or v[i] > v[i + 1]) continue; int l = i, r = i; long long s = 0, t = 0; while(s < ans and r - l < n) { if(v[l - 1] < v[r]) { auto e = --l; if(v[e] > t) s += v[e] - t, t = v[e]; l = max(L[l] + 1, r - n); t += V[e + 1] - V[l]; } else { auto e = r++; if(v[e] > t) s += v[e] - t, t = v[e]; r = min(R[r - 1], l + n); t += V[r] - V[e]; } } ans = min(ans, s); } cout << ans << endl; }