/** * This solution implicitly builds a binary tree by * removing the nodes from lowest to highest level and * adding their worth and costs to their neighbours */ #include #include #include #include using namespace std; typedef struct Node { Node() : left(nullptr),l_worth(0), right(nullptr), r_worth(0) {} Node *left; long long l_worth; Node *right; long long r_worth; long long level; long long req_lvl; } Node; int main() { size_t n; cin >> n; vector nodes(n); vector levels(n); long long highest_level = 0; size_t highest_level_index = 0; for(size_t i = 0; i < n; ++i) { long long level; cin >> level; levels[i] = level; if(level > highest_level) { highest_level_index = i; highest_level = level; } } size_t j = highest_level_index; vector> q(n); for(size_t i = 0; i < n; ++i) { nodes[i].level = levels[j]; nodes[i].req_lvl = nodes[i].level; q[i] = make_pair( nodes[i].level, &nodes[i] ); j = (j + 1) % n; } Node empty; empty.right = &nodes[0]; empty.left = &nodes[n - 1]; nodes[0].left = ∅ nodes[n - 1].right = ∅ for(size_t i = 0; i < n - 1; ++i) { nodes[i].right = &nodes[i + 1]; nodes[i + 1].left = &nodes[i]; } sort(q.begin(), q.end()); for( const auto &p : q ) { const Node *me = p.second; Node *left = p.second->left; Node *right = p.second->right; long long worth = me->l_worth + me->level + me->r_worth; // Blindly overwriting works since we will only visit // the neighbours when it is cheapest to do so => // worth can only increase, req_level can only decrease // (we still need std::min, since req_level comes from 2 sides) left->r_worth = worth; left->req_lvl = min( left->req_lvl, max( left->level - worth, me->req_lvl ) ); right->l_worth = worth; right->req_lvl = min( right->req_lvl, max( right->level - worth, me->req_lvl ) ); // Remove self left->right = right; right->left = left; } cout << q.back().second->req_lvl << endl; return 0; }