// テ・ツ淞コテヲツ慊ャテ」ツδ?」ツδウテ」ツδ療」ツδャテ」ツδシテ」ツδ?

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
using namespace std;

#define rep(i,a,n) for(int (i)=(a); (i)<(n); (i)++)
#define repq(i,a,n) for(int (i)=(a); (i)<=(n); (i)++)
#define repr(i,a,n) for(int (i)=(a); (i)>=(n); (i)--)
#define int long long int

template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
constexpr ll INF = 1001001001001001LL;
constexpr ll MOD = 1000000007LL;

constexpr ll SIZE = 1LL << 17;

template <typename T>
struct LazySegtree {
    T node[2*SIZE], lazy[2*SIZE];

    // テ・ツ按敕ヲツ慊淌・ツ個?
    LazySegtree() {}
    LazySegtree(vector<T> v) {
        for(size_t i=0; i<v.size(); ++i) {
            node[SIZE-1+i] = v[i];
        }
        for(int i=SIZE-2; i>=0; i--) {
            node[i] = node[2*i+1] + node[2*i+2];
        }
    }

    // テゥツ??・ツサツカティツゥツ陛、ツセツ。
    void lazyUpdate(int a, int b, int k) {
        int rng = b - a;
        node[k] += lazy[k];
        if(rng > 1) {
            lazy[2*k+1] += lazy[k];
            lazy[2*k+2] += lazy[k];
        }
        lazy[k] = 0;
    }

    // テァツッツ?・ツ崢イ [a, b) テ」ツ?ォ x テ」ツつ津ィツカツウテ」ツ??
    void add(int a, int b, T x, int l=0, int r=SIZE, int k=0) {
        lazyUpdate(l, r, k);
        if(b <= l || r <= a) return;
        if(a <= l && r <= b) {
            lazy[k] += x;
            lazyUpdate(l, r, k);
        }
        else {
            int mid = (l + r) / 2;
            add(a, b, x, l, mid, 2*k+1);
            add(a, b, x, mid, r, 2*k+2);
            node[k] = min(node[2*k+1], node[2*k+2]);
        }
    }

    // テァツッツ?・ツ崢イ [a, b) テ」ツ?ョテヲツ慊?・ツーツ湘・ツ?、
    T query(int a, int b, int l=0, int r=SIZE, int k=0) {
        lazyUpdate(l, r, k);
        if(b <= l || r <= a) return INF;
        if(a <= l && r <= b) return node[k];
        int mid = (l + r) / 2;
        T vl = query(a, b, l, mid, 2*k+1);
        T vr = query(a, b, mid, r, 2*k+2);
        return min(vl, vr);
    }
};

int W;
int a[100010];

signed main() {
    cin >> W;
    vector<int> doors;
    doors.push_back(-INF); // テァツ閉ェテ・ツ?オ
    LazySegtree<int> seg(vector<int>(W, 0));
    rep(i,0,W) {
        cin >> a[i];
        if(a[i] < 0) seg.add(i, i+1, -a[i]);
        else seg.add(i, i+1, INF);

        if(a[i] == 0) doors.push_back(i);
    }
    doors.push_back(INF); // テァツ閉ェテ・ツ?オ

    rep(i,0,W) seg.add(i, i+1, -i);
    int ans = 0;
    rep(i,0,W) {
        if(a[i] > 0) {
            int l = upper_bound(doors.begin(), doors.end(), i) - doors.begin() - 1;
            int r = l + 1;
            int ad = 0;
            if(abs(doors[l]) != INF) {
                int val = seg.query(doors[l], i);
                chmax(ad, val);
            }
            if(abs(doors[r]) != INF) {
                int val = seg.query(i, doors[r]);
                chmax(ad, val);
            }
            ans += min(a[i], ad);
        }
        seg.add(0, i+1, -1);
        seg.add(i+1, W, 1);
    }
    cout << ans << endl;
    return 0;
}

Measured memory_bytes: 8692