#include using namespace std; #define rep(i,a,b) for(auto i = (a); i < (b); i++) #define pb push_back #define fs first #define sc second typedef long long ll; typedef pair ii; typedef vector vi; typedef vector vvi; typedef vector vii; typedef vector vvii; const double EPS = 1e-9; struct node { ll mx; ll index; node(ll _val, ll _index) { mx = _val; index = _index; }; node(node a, node b) { if(a.mx > b.mx) { mx = a.mx; index = a.index; } else { mx = b.mx; index = b.index; } } }; struct segment_tree { ll sz, n; vector t; segment_tree(ll _n) : sz(_n*4), n(_n) { rep(i,0,sz) t.pb(node(-1,-1)); } void build(vii &a, ll v=1, ll tl=0, ll tr=-1) { if(tr == -1) tr = n-1; if(tl == tr) { t[v] = node(a[tl].fs, a[tl].sc); } else { ll tm = (tl+tr)/2; build(a, v*2, tl, tm); build(a, v*2+1, tm+1, tr); t[v] = node(t[v*2], t[v*2+1]); } } node query(ll l, ll r, ll v=1, ll tl=0, ll tr=-1) { if(tr == -1) tr = n-1; if(l > r) return node(-1, -1); if(l == tl && r == tr) return t[v]; ll tm = (tl+tr)/2; return node( query(l,min(r,tm), v*2, tl, tm), query(max(l,tm+1), r, v*2+1, tm+1, tr)); } }; vi A; // min_cost, total ii join(ii a, ii b, ll i) { ll total = 0; ll min_cost = 0; // take the left dude if(a.sc >= A[i]) { total = A[i] + a.sc + b.sc - b.fs; min_cost = a.fs; } else { // don'e have enough ll need = A[i] - a.sc; total = A[i] + a.sc + b.sc - b.fs + need; min_cost = a.fs + need; } if(b.sc >= A[i]) { if(b.fs < min_cost) { total = A[i] + b.sc + a.sc - a.fs; min_cost = b.fs; } } else { // don'e have enough ll need = A[i] - b.sc; if(b.fs + need < min_cost) { total = A[i] + b.sc + a.sc - a.fs + need; min_cost = b.fs + need; } } return ii(min_cost, total); } // returns (min_cost, total) ii solve(ll l, ll r, segment_tree &sq) { if(l > r) return ii(0, 0); if(l == r) return ii(A[l], 2*A[l]); if(l+1 == r) { // special case ll mn = min(A[l], A[r]); ll mx = max(A[l], A[r]); ll cost = mn; if(mn*2 < mx) cost += mx - mn*2; return ii(cost, cost + mn + mx); } ll mx_index = sq.query(l,r).index; //ll mx_index = l; // do this fast //rep(i,l,r+1) if(A[i] > A[mx_index]) mx_index = i; ii t1 = solve(l, mx_index - 1, sq); ii t2 = solve(mx_index + 1,r, sq); return join(t1, t2, mx_index); } int main() { cin.sync_with_stdio(false); ll n; cin >> n; A = vi(n*2); rep(i,0,n) cin >> A[i]; rep(i,0,n) A[i+n] = A[i]; ll mx_index = 0; vii R; rep(i,0,2*n) R.pb(ii(A[i], i)); segment_tree sq(n*2); sq.build(R); rep(i,0,n) if(A[i] > A[mx_index]) mx_index = i; ii sol = solve(mx_index, mx_index+n-1, sq); cout << sol.fs << endl; }