#include #include using namespace std; using ll = long long; using S = tuple; using F = int; // 単位元 constexpr S e(){return make_tuple(0, 1 << 30, 0);} // 区間演算 constexpr S op(S lhs, S rhs){ auto [lsum, lmn, lsz] = lhs; auto [rsum, rmn, rsz] = rhs; return make_tuple(lsum + rsum, min(lmn, rmn), lsz + rsz); } // x に f を作用させた時の変化 constexpr S mapping(F f, S x){ if(f >> 30) return x; auto [sm, mn, sz] = x; return make_tuple(sz * (ll)f, f, sz); } // bf を作用させた後に af を作用させる constexpr F composition(F af, F bf){return min(af, bf);} // 恒等写像 constexpr F id(){return 1 << 30;} int main(){ ios::sync_with_stdio(false); cin.tie(0); int n, idx = 0; cin >> n; vector> E(3 * n + 2); vector tmp(n + 1); for(int i = 0; i <= n; i++) E[idx++] = make_pair(i, -1); for(int i = 0; i < n; i++){ tmp[i] = make_tuple(n - i, n - i, 1); cin >> E[idx].first; E[idx].first--; E[idx++].second = i; } for(int i = 0; i <= n; i++) E[idx++] = make_pair(i, n); atcoder::internal::csr g(n + 1, E); atcoder::lazy_segtree seg(tmp); ll ans = n * (ll)(n + 1) / 2; for(int i = 0; i <= n; i++){ for(int j = g.start[i]; j + 1 < g.start[i + 1]; j++){ int l = g.elist[j] + 1, r = g.elist[j + 1] + 1, pr = n + 1 - r; r = min(r, seg.max_right(l, [&](S v){return get<1>(v) > pr;})); if(l < r) seg.apply(l, r, pr); } ans += get<0>(seg.all_prod()); } cout << ans << '\n'; }