/** * Intended solution building the tree in O(nlogn) */ #include #include #include #include using namespace std; typedef struct Node { Node() : parent(nullptr), left(nullptr), right(nullptr) {} Node *parent; Node *left; Node *right; long long level; long long worth; long long req_lvl; } Node; static void build_heap(vector &nodes) { vector> q; q.reserve(nodes.size()); for(size_t i = 0; i < nodes.size(); ++i) q.push_back({nodes[i].level, i}); sort(q.begin(), q.end(), std::greater>()); set positions; for(const pair &p : q) { Node &elem = nodes[p.second]; Node *left = nullptr, *right = nullptr; auto left_it = positions.lower_bound(p.second); auto right_it = positions.upper_bound(p.second); if(left_it != positions.begin()) left = &nodes[*(--left_it)]; if(right_it != positions.end()) right = &nodes[*right_it]; if(left) { if(right && right->level < left->level) { right->left = &elem; elem.parent = right; } else { left->right = &elem; elem.parent = left; } } else { if(right) { right->left = &elem; elem.parent = right; } } positions.insert(p.second); } } static void fill(Node &node) { node.worth = node.level; node.req_lvl = node.level; if(node.left) { fill(*node.left); node.worth += node.left->worth; node.req_lvl = min(node.req_lvl, max(node.left->req_lvl, node.level - node.left->worth)); } if(node.right) { fill(*node.right); node.worth += node.right->worth; node.req_lvl = min(node.req_lvl, max(node.right->req_lvl, node.level - node.right->worth)); } } 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 i = highest_level_index; for(Node &node : nodes) { node.level = levels[i]; i = (i + 1) % n; } build_heap(nodes); Node *root = nullptr; for(Node &node : nodes) { if(!node.parent) root = &node; } fill(*root); cout << root->req_lvl << endl; return 0; }