#include #define int long long using namespace std; struct rmq { vector> rmq; vector lg; void build(vector a) { int n = a.size() - 1; lg = vector(n + 1); for (int i = 2; i <= n; ++i) { lg[i] = lg[i / 2] + 1; } rmq = vector>(n + 1, vector(lg[n] + 1)); for (int i = 1; i <= n; ++i) { rmq[i][0] = a[i]; } for (int j = 1; j <= lg[n]; ++j) { for (int i = 1; i + (1 << j) - 1 <= n; ++i) { rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]); } } } int query(int st, int dr) { int pow_2 = lg[dr - st + 1]; return min(rmq[st][pow_2], rmq[dr - (1 << pow_2) + 1][pow_2]); } }; const int nmax = 2e5; const int vmax = 2e5; struct aib { int n; vector a; void resize(int _n) { n = _n; a = vector(n + 1); } void update(int pos, int val) { for (int i = pos; i <= n; i += i & (-i)) { a[i] += val; } } void clear(int pos) { for (int i = pos; i <= n; i += i & (-i)) { a[i] = 0; } } int query(int pos) { if (pos < 0) { return 0; } int ans = 0; for (int i = pos; i; i -= i & (-i)) { ans += a[i]; } return ans; } }; vector a; aib tree; rmq adam; int divide(int st, int dr) { if (st == dr) { return 1; } int mid = (st + dr) / 2; int ans = divide(st, mid) + divide(mid + 1, dr); int p1 = mid + 1, p2 = mid + 1; int maxi = 0, mini = INT_MAX; for (int i = mid; i >= st; --i) { maxi = max(maxi, a[i]); mini = min(mini, a[i]); while (p2 <= dr && a[p2] <= maxi) { tree.update(adam.query(mid + 1, p2) + (p2 - mid), 1); p2++; } while (p1 <= dr && a[p1] >= mini) { tree.update(adam.query(mid + 1, p1) + (p1 - mid), -1); p1++; } int l = p1, r = p2 - 1; if (l <= r) { ans += tree.query(maxi - (mid - i + 1) + 1); } int cnt = min(l, r + 1) - (mid + 1); ans += max(0ll, min(cnt, maxi - mini + 1 - (mid - i + 1))); } for (int i = mid + 1; i <= dr; ++i) { tree.clear(adam.query(mid + 1, i) + (i - mid)); } p1 = mid, p2 = mid; maxi = 0, mini = INT_MAX; for (int i = mid + 1; i <= dr; ++i) { maxi = max(maxi, a[i]); mini = min(mini, a[i]); while (p2 >= st && a[p2] < maxi) { tree.update(adam.query(p2, mid) + (mid - p2 + 1), 1); p2--; } while (p1 >= st && a[p1] >= mini) { tree.update(adam.query(p1, mid) + (mid - p1 + 1), -1); p1--; } int l = p2 + 1, r = p1; if (l <= r) { ans += tree.query(maxi - (i - mid) + 1); } int cnt = mid - max(l - 1, r); ans += max(0ll, min(cnt, maxi - mini + 1 - (i - mid))); } for (int i = mid; i >= st; --i) { tree.clear(adam.query(i, mid) + (mid - i + 1)); } return ans; } int32_t main() { cin.tie(nullptr)->sync_with_stdio(false); int n; cin >> n; a = vector(n + 1); for (int i = 1; i <= n; ++i) { cin >> a[i]; } adam.build(a); tree.resize(nmax + vmax); cout << divide(1, n); }