int L=mid+1,R=mid+1;//右端点可以到达的区间 for (registerint i=mid;i>=l;--i){ while (R<=r&&rmin[R]>lmin[i]) cnt[R-rmax[R]+N]++,R++; while (L<R&&rmax[L]<lmax[i]) cnt[L-rmax[L]+N]--,L++; ans+=cnt[i-lmin[i]+N]; } while (L<R) cnt[L-rmax[L]+N]--,L++;
#include<bits/stdc++.h> #define MAXN 300005 #define N 300000 #define int long long usingnamespace std; inlineintread(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+(ch^'0'); ch=getchar(); } return x*f; } int a[MAXN]; int lmax[MAXN],lmin[MAXN],rmax[MAXN],rmin[MAXN]; //l,r是指在终点的哪一边 inlineintQueryMax(int l,int r){//满足l <= mid <= r returnmax(lmax[l],rmax[r]); } inlineintQueryMin(int l,int r){//满足l <= mid <= r returnmin(lmin[l],rmin[r]); } longlong ans; int cnt[MAXN*2]; voidCDQ(int l,int r){ if (l==r){ ans++;//一个也有贡献 return ; } int mid=(l+r)>>1; CDQ(l,mid),CDQ(mid+1,r); lmax[mid]=lmin[mid]=a[mid]; for (registerint i=mid-1;i>=l;--i) lmax[i]=max(a[i],lmax[i+1]),lmin[i]=min(a[i],lmin[i+1]); rmax[mid+1]=rmin[mid+1]=a[mid+1]; for (registerint i=mid+2;i<=r;++i) rmax[i]=max(a[i],rmax[i-1]),rmin[i]=min(a[i],rmin[i-1]); //初始化结束 //max,min都在左边,右边 //r-l=max-min -> r=max-min+l for (registerint i=mid;i>=l;--i){ int j=lmax[i]-lmin[i]+i; if (j<=r&&j>mid&&QueryMax(i,j)==lmax[i]&&QueryMin(i,j)==lmin[i]) ans++; } //l-r=min-max -> l=min-max+r for (registerint i=mid+1;i<=r;++i){ int j=rmin[i]-rmax[i]+i;//注意算出来的是左端点 if (j>=l&&j<=mid&&QueryMax(j,i)==rmax[i]&&QueryMin(j,i)==rmin[i]) ans++; } //max,min一个在左边,一个在右边,开一个桶记录 //l-r=min-max -> l-min=r-max 或者 l+max=r+min //左边有最小值 int L=mid+1,R=mid+1;//右端点可以到达的区间 for (registerint i=mid;i>=l;--i){ while (R<=r&&rmin[R]>lmin[i]) cnt[R-rmax[R]+N]++,R++; while (L<R&&rmax[L]<lmax[i]) cnt[L-rmax[L]+N]--,L++; ans+=cnt[i-lmin[i]+N]; } while (L<R) cnt[L-rmax[L]+N]--,L++; //左边有最大值 L=mid,R=mid;//右端点可以到达的区间 for (registerint i=mid+1;i<=r;++i){ while (L>=l&&lmin[L]>rmin[i]) cnt[L+lmax[L]]++,L--; while (L<R&&lmax[R]<rmax[i]) cnt[R+lmax[R]]--,R--; ans+=cnt[i+rmin[i]]; } while (R>L) cnt[R+lmax[R]]--,R--; } signedmain(){ //freopen("CF536F.in","r",stdin); int n=read(); for (registerint i=1;i<=n;++i){ int x=read(),y=read(); a[x]=y; } CDQ(1,n); printf("%I64d\n",ans);;;;; } /* 5 1 1 4 3 3 2 2 4 5 5 */