#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
    vector<int> parent, sz;
    // cost: minimum enhancements needed for this contiguous block
    // level: the common “activation” level for this block (the value at which it was raised)
    vector<long long> cost, level;
    long long ans;  // global answer: sum of costs over active blocks
    UnionFind(int n) : parent(n), sz(n, 1), cost(n, 0), level(n, 0), ans(0) {
        for (int i = 0; i < n; i++)
            parent[i] = i;
    }
    int find(int v) {
        if (v == parent[v])
            return v;
        return parent[v] = find(parent[v]);
    }
    // Merge two adjacent blocks a and b.
    // The new block's level becomes min(level[a], level[b]).
    // If the two blocks have the same level, then they share one enhancement,
    // so we subtract 1 from the sum of their costs.
    void merge(int a, int b) {
        a = find(a);
        b = find(b);
        if (a == b)
            return;
        // Remove the old blocks’ costs from the global answer.
        ans -= cost[a];
        ans -= cost[b];
        // Union by size.
        if (sz[a] < sz[b])
            swap(a, b);
        parent[b] = a;
        sz[a] += sz[b];
        long long newLevel = min(level[a], level[b]);
        long long newCost;
        if (level[a] == level[b])
            newCost = cost[a] + cost[b] - 1;
        else
            newCost = cost[a] + cost[b];
        level[a] = newLevel;
        cost[a] = newCost;
        ans += cost[a];
    }
};
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<long long> a(n);
    for (int i = 0; i < n; i++){
        cin >> a[i];
    }
    // We only “activate” indices with a positive final value.
    vector<bool> active(n, false);
    UnionFind uf(n);
    // Create vector of (value, index) for indices with a[i] > 0.
    vector<pair<long long, int>> nodes;
    for (int i = 0; i < n; i++){
        if(a[i] > 0)
            nodes.push_back({a[i], i});
    }
    // Process in decreasing order.
    sort(nodes.begin(), nodes.end(), [](auto &p1, auto &p2){
        return p1.first > p2.first;
    });
    // Activate indices in descending order.
    for (auto &p : nodes) {
        long long val = p.first;
        int idx = p.second;
        active[idx] = true;
        uf.cost[idx] = 1;   // Activation cost: one enhancement for this index.
        uf.level[idx] = val; // Store the final value at this index.
        uf.ans += 1;        // Increase global answer.
        if (idx - 1 >= 0 && active[idx - 1]) {
            uf.merge(idx, idx - 1);
        }
        if (idx + 1 < n && active[idx + 1]) {
            uf.merge(idx, idx + 1);
        }
    }
    
    cout << uf.ans << "\n";
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |