#include <algorithm> #include <cstdio> #include <cstring> #include <iostream> #include <map> using namespace std; struct Rhine_Lab { Rhine_Lab() { freopen("easy.in", "r", stdin); freopen("easy.out", "w", stdout); } }; Rhine_Lab Ptilopsis_w;
const int N = 1e5+10; const int INF = 0x3f3f3f3f;
namespace tree { struct node { int l, r; int min, cnt; int lz; } a[N*4]; void build(int l, int r, int i = 1); void add(int ql, int qr, int val, int i = 1); node query(int ql, int qr, int i = 1); }
struct stack { int a[N], tp; stack() { tp = 0; memset(a, 0, sizeof(a)); } void push(int x) { a[++tp] = x; } int top() { return tp ? a[tp] : 0; } int bottom() { return a[1]; } int second() { return tp ? a[tp-1] : 0; } void pop() { if(tp) a[tp--] = 0; } int size() { return tp; } };
int n; int a[N]; map<int,int> pos; int last[N]; stack stmax, stmin;
int main() { cin >> n; for(int i = 1; i <= n; i++) { cin >> a[i]; last[i] = pos[a[i]]; pos[a[i]] = i; } long long ans = 0; tree::build(1, n); for(int i = 1; i <= n; i++) { tree::add(last[i]+1, i, -1); while(stmax.size()&&a[stmax.top()]<a[i]) { tree::add(stmax.second()+1, stmax.top(), a[i]-a[stmax.top()]); stmax.pop(); } stmax.push(i); while(stmin.size()&&a[stmin.top()]>a[i]) { tree::add(stmin.second()+1, stmin.top(), a[stmin.top()]-a[i]); stmin.pop(); } stmin.push(i); auto tmp = tree::query(1, i); if(tmp.min == -1) ans += tmp.cnt; } cout << ans << "\n"; }
namespace tree { #define ls (i<<1) #define rs (i<<1|1) node operator + (node a, node b) { node c; c.l = a.l, c.r = b.r; c.min = min(a.min, b.min); if(a.min == b.min) c.cnt = a.cnt+b.cnt; else if(a.min < b.min) c.cnt = a.cnt; else c.cnt = b.cnt; c.lz = 0; return c; } void add(node &i, int val) { i.min += val; i.lz += val; } void push_down(int i) { if(!a[i].lz) return; add(a[ls], a[i].lz); add(a[rs], a[i].lz); a[i].lz = 0; } void build(int l, int r, int i) { a[i].l = l, a[i].r = r; if(l == r) { a[i].min = 0; a[i].cnt = 1; return void(); } int mid = (l+r)>>1; build(l, mid, ls); build(mid+1, r, rs); a[i] = a[ls]+a[rs]; } void add(int ql, int qr, int val, int i) { if(ql <= a[i].l and a[i].r <= qr) return add(a[i], val); push_down(i); if(ql <= a[ls].r) add(ql, qr, val, ls); if(qr >= a[rs].l) add(ql, qr, val, rs); a[i] = a[ls]+a[rs]; } node query(int ql, int qr, int i) { if(ql <= a[i].l and a[i].r <= qr) return a[i]; push_down(i); node ans; if(qr <= a[ls].r) return query(ql, qr, ls); if(ql >= a[rs].l) return query(ql, qr, rs); return query(ql, qr, ls)+query(ql, qr, rs); } }
|