/** * Solution as described in the solution outlines */ #include #include typedef unsigned long long ull; typedef struct Element { Element( ull spice, std::size_t id, std::size_t n ) { left = (id + n - 1) % n; right = (id + 1) % n; spiciness = spice; gain = spice; } std::size_t left = 0; std::size_t right = 0; ull spiciness; ull gain; } Element; bool try_solve( const std::vector &slices, ull tolerance ) { // create cyclic linked list const std::size_t n = slices.size(); std::vector cll; cll.reserve( n ); for( std::size_t i = 0; i < n; ++i ) { cll.emplace_back( slices[i], i, n ); } std::size_t visit = 0; std::size_t visit_next = 0; do { visit = visit_next; Element ¤t = cll[visit]; // Only one element left? if( visit == current.left ) return true; Element &left = cll[current.left]; Element &right = cll[current.right]; if( tolerance >= current.spiciness ) { ull new_tolerance = tolerance + current.gain; if( left.spiciness <= new_tolerance ) { current.spiciness = std::min( current.spiciness, left.spiciness ); current.gain += left.gain; current.left = left.left; cll[left.left].right = visit; } else if( right.spiciness <= new_tolerance) { current.spiciness = std::min( current.spiciness, right.spiciness ); current.gain += right.gain; current.right = right.right; cll[right.right].left = visit; } else { visit_next = current.right; } } else { visit_next = current.right; } } while( visit <= visit_next); return false; } int main() { ull n; std::cin >> n; std::vector slices(n); ull poss_tol = 0; for( ull &slice : slices ) { std::cin >> slice; poss_tol = std::max( poss_tol, slice ); } // unsigned long long ftw if( poss_tol == 0 ) { std::cout << 0 << std::endl; return 0; } ull imposs_tol = 0; while( imposs_tol + 1 < poss_tol ) { ull test_tol = (imposs_tol + poss_tol) / 2; if( try_solve(slices, test_tol) ) poss_tol = test_tol; else imposs_tol = test_tol; } std::cout << poss_tol << std::endl; return 0; }