#include using namespace std; #define int long long int n,v[200005]; int ans; void solvell(int l,int r)///ambele in stanga { int mij = (l + r) / 2; int rmax = mij + 1; int maxst = 0,minst = 1e9; for (int i = mij; i >= l; i--) { maxst = max(maxst,v[i]); minst = min(minst,v[i]); while (rmax <= r and v[rmax] <= maxst and v[rmax] >= minst) rmax++; int topr = maxst - minst + i; int rreal = min(topr,rmax - 1); ans += max(0ll,rreal - mij); } } void solverr(int l,int r)///ambele in dreapta { int mij = (l + r) / 2; int lmax = mij; int maxdr = 0,mindr = 1e9; for (int i = mij + 1; i <= r; i++) { maxdr = max(maxdr,v[i]); mindr = min(mindr,v[i]); while (lmax >= l and v[lmax] < maxdr and v[lmax] > mindr) lmax--; int topl = i - maxdr + mindr; int lreal = max(topl,lmax + 1); ans += max(0ll,mij - lreal + 1); } } struct ura { int l,r,val; }; vectorqueries; void addquery(int l,int r,int val) { ura aux; aux.l = l; aux.r = r; aux.val = val; queries.push_back(aux); } int aib[200005]; vector>updates; void update(int pos,int val) { for (int i = pos; i <= n; i += (i & -i)) aib[i] += val; } int query(int pos) { int x = 0; for (int i = pos; i > 0; i -= (i & -i)) x += aib[i]; return x; } void upd(int pos,int val) { updates.push_back({pos,val}); update(pos,val); } void resetaib() { for (auto it : updates) update(it.first,-it.second); updates.clear(); } bool cmp(ura A,ura B) { return A.val < B.val; } void solvequeries(int l,int r) { sort(queries.begin(),queries.end(),cmp); vector>values; int mxx = 0; int mij = (l + r) / 2; for (int i = mij + 1; i <= r; i++) { mxx = max(mxx,v[i]); values.push_back({i - mxx,i}); } sort(values.begin(),values.end()); int i1 = 0; for (int i = 0; i < queries.size(); i++) { while (i1 < values.size() and values[i1].first <= queries[i].val) upd(values[i1].second,1ll),i1++; ans += query(queries[i].r) - query(queries[i].l - 1); } resetaib(); } void solvelr(int l,int r)///min in stanga,max in dreapta { int mij = (l + r) / 2; int maxst = 0,minst = 1e9; vectorpremax(r - mij + 2); premax[1] = v[mij + 1]; for (int i = mij + 2; i <= r; i++) premax[i - mij] = max(premax[i - mij - 1],v[i]); int rmin = mij + 1,rmax = mij + 1;///nu se poate r < rmin fiindca nu ar mai fi max in dreapta, nu se poate r >= rmax fiindca ar fi min in dreapta for (int i = mij; i >= l; i--) { maxst = max(maxst,v[i]); minst = min(minst,v[i]); while (rmin <= r and premax[rmin - mij] <= maxst) rmin++; while (rmax <= r and v[rmax] >= minst) rmax++; //if (l == 1 and r == 10) // cout << i << ' ' << rmin << ' ' << rmax << '\n'; if (rmin <= rmax - 1) { ///ma intreb cate valori intre rmin si rmax - 1 sunt valide ///o valoare e valida daca r - maxpref[r] <= l - minst addquery(rmin,rmax - 1,i - minst); } } solvequeries(l,r); queries.clear(); } struct ura2 { int l,r,val; }; vectorqueries2; void addquery2(int l,int r,int val) { ura2 aux; aux.l = l; aux.r = r; aux.val = val; queries2.push_back(aux); } int aib2[200005]; vector>updates2; void update2(int pos,int val) { for (int i = pos; i <= 2 * n; i += (i & -i)) aib2[i] += val; } int query2(int pos) { int x = 0; for (int i = pos; i > 0; i -= (i & -i)) x += aib2[i]; return x; } void upd2(int pos,int val) { updates2.push_back({pos,val}); update2(pos,val); } void resetaib2() { for (auto it : updates2) update2(it.first,-it.second); updates2.clear(); } bool cmp2(ura2 A, ura2 B) { return A.val < B.val; } void solvequeries2(int l,int r) { sort(queries2.begin(),queries2.end(),cmp2); vector>values; int mij = (l + r) / 2; int mxx = 0; for (int i = mij; i >= l; i--) { mxx = max(mxx,v[i]); values.push_back({i + mxx,i}); } sort(values.begin(),values.end()); int i1 = 0; for (int i = 0; i < queries2.size(); i++) { while (i1 < values.size() and values[i1].first < queries2[i].val) upd2(values[i1].second,1),i1++; ans += (queries2[i].r - queries2[i].l + 1); ans -= (query2(queries2[i].r) - query2(queries2[i].l - 1)); } resetaib2(); } void solverl(int l,int r)///min in dreapta,max in stanga { int mij = (l + r) / 2; int maxdr = 0,mindr = 1e9; vectorsufmax(mij - l + 2); sufmax[mij - l + 1] = v[mij]; for (int i = mij - 1; i >= l; i--) sufmax[i - l + 1] = max(sufmax[i - l + 2],v[i]); int lmin = mij,lmax = mij;///nu se poate l > lmax fiindca nu ar mai fi max in stanga, nu se poate l <= lmin fiindca ar fi min in stanga for (int i = mij + 1; i <= r; i++) { maxdr = max(maxdr,v[i]); mindr = min(mindr,v[i]); while (lmax >= l and sufmax[lmax - l + 1] < maxdr) lmax--; while (lmin >= l and v[lmin] > mindr) lmin--; //if (l == 1 and r == 9) // cout << i << ' '<< lmin << ' ' << lmax << '\n'; if (lmin + 1 <= lmax) { ///ma intreb cate valori intre lmin + 1 si lmax sunt valide ///o valoare e valida daca l + maxsuf[l] >= r + mindr addquery2(lmin + 1,lmax,i + mindr); } } solvequeries2(l,r); queries2.clear(); } void solve(int l,int r) { if (l > r) return; if (l == r) { ans++; return; } int mij = (l + r) / 2; solve(l,mij); solve(mij + 1,r); //cout << l << ' ' << r << ' '; solvell(l,r); //cout << ans - d1 << ' '; solverr(l,r); //cout << ans - d1 << ' '; solvelr(l,r); //cout << ans - d1 << ' '; solverl(l,r); //cout << ans - d1 << '\n'; } signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> n; for (int i = 1; i <= n; i++) cin >> v[i]; solve(1,n); cout << ans; return 0; }