先把一维拍扁,那么问题就转化成了求这个的个数,\(\max-\min= r-l\)
变一下,\(\max - \min -len=-1\)
枚举右端点,发现每次一定存在-1,然后可以在线段树上维护这个式子的最小值及个数
每次单调栈退栈和进栈时,在线段树上更新值
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf=0x3ffffffffffffff;
const int N=3e5+11;
struct tree{
int l,r;
int num;
int sum,lazy;
}tre[4*N];
struct sta_{
int i;
int l,x;
}sp[N],sd[N];
int n;
int ans;
int tp,td;
int a[N];
inline int read()
{
int s=0;
char ch=getchar();
while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9')
{
s=(s<<1)+(s<<3)+(ch^48);
ch=getchar();
}
return s;
}
void pushdown(int i)
{
if(tre[i].l==tre[i].r)return;
tre[i<<1].lazy+=tre[i].lazy;
tre[i<<1|1].lazy+=tre[i].lazy;
tre[i<<1].sum+=tre[i].lazy;
tre[i<<1|1].sum+=tre[i].lazy;
tre[i].lazy=0;
return;
}
void update(int i)
{
tre[i].sum=tre[i<<1].sum,tre[i].num=tre[i<<1].num;
if(tre[i<<1|1].sum==tre[i<<1].sum) tre[i].num+=tre[i<<1|1].num;
if(tre[i<<1|1].sum<tre[i<<1].sum) tre[i].sum=tre[i<<1|1].sum,tre[i].num=tre[i<<1|1].num;
return;
}
void insert(int i,int l,int r,int sum)
{
if(tre[i].lazy) pushdown(i);
if(tre[i].l>=l&&tre[i].r<=r)
{
tre[i].sum+=sum;
tre[i].lazy+=sum;
return;
}
int mid=(tre[i].l+tre[i].r)>>1;
if(l<=mid) insert(i<<1,l,r,sum);
if(r>mid) insert(i<<1|1,l,r,sum);
update(i);
return;
}
void build(int i,int l,int r)
{
tre[i].l=l;
tre[i].r=r;
if(l==r) {tre[i].num=1;return;}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
return;
}
signed main()
{
n=read();
for(int i=1;i<=n;++i) a[read()]=read();
build(1,1,n);
for(int i=1;i<=n;++i)
{
int lp=i,ld=i;
while(tp&&sp[tp].x<a[i]) insert(1,sp[tp].l,sp[tp].i,-sp[tp].x),lp=sp[tp].l,--tp;
while(td&&sd[td].x>a[i]) insert(1,sd[td].l,sd[td].i,sd[td].x),ld=sd[td].l,--td;
if(i-1) insert(1,lp,i-1,a[i]),insert(1,ld,i-1,-a[i]),insert(1,1,i-1,-1);
insert(1,i,i,-1);
sp[++tp]=(sta_){i,lp,a[i]};
sd[++td]=(sta_){i,ld,a[i]};
ans+=tre[1].num;
}
cout<<ans<<endl;
return 0;
}