1 #include<cstdio>
2 #include<algorithm>
3 using namespace std;
4 const int maxn=50000+10;
5 int a[maxn],Min[maxn],Max[maxn],cnt[maxn<<1];
6 int ans=0,n;
7 void Divi(int l,int r){
8 if(l==r){
9 ans++;
10 return;
11 }//当只有一个点时,一定为一个完美子图,ans++
12 int mid=(l+r)>>1;
13 Divi(l,mid);//递归左边
14 Divi(mid+1,r);//递归右边
15 Min[mid]=Max[mid]=a[mid];
16 Min[mid+1]=Max[mid+1]=a[mid+1];
17 for(int i=mid-1;i>=l;i--){
18 Min[i]=min(Min[i+1],a[i]);
19 Max[i]=max(Max[i+1],a[i]);
20 }
21 for(int i=mid+2;i<=r;i++){
22 Min[i]=min(Min[i-1],a[i]);
23 Max[i]=max(Max[i-1],a[i]);
24 }//初始化,Max,Min都是对于mid而言
25 for(int i=mid;i>=l;i--){
26 int j=i+Max[i]-Min[i];
27 if(j<=r&&j>mid&&Max[j]<Max[i]&&Min[i]<Min[j]) ans++;
28 }//最大最小值都在左端,判断时保证j在右端
29 for(int j=mid+1;j<=r;j++){
30 int i=j-Max[j]+Min[j];
31 if(i>=l&&i<=mid&&Max[i]<Max[j]&&Min[i]>Min[j]) ans++;
32 }//最大最小值都在右端,判断时i在左端
33 int j=mid+1,k=mid+1;
34 for(int i=mid;i>=l;i--){//左小右大
35 while(j<=r&&Min[j]>Min[i]){//j满足左小
36 cnt[Max[j]-j+n]++;
37 j++;
38 }//因为Max[j]-j可能为负数,所以加n
39 //不改变j的值,因为第一个while中若新的i的Min[i]不变,一定会走到当前的j,若更小,一定会走到当前的j,且可能向后走
40 while(k<j&&Max[i]>Max[k]){//若不满足右大,cnt--,因为若左大左小,前面已经计算过
41 cnt[Max[k]-k+n]--;
42 k++;
43 }//不改变k的值,因为第二个while中若新的i的Max[i]不变,一定会走到当前的k,若更大,一定会走到当前的k,且可能向后走
44 ans+=cnt[Min[i]-i+n];//因为Max[j]-j==Min[i]-i
45 }
46 while(k<j){
47 cnt[Max[k]-k+n]--;
48 k++;
49 }//不用memset,会T掉
50 j=mid,k=mid;
51 for(int i=mid+1;i<=r;i++){
52 while(j>=l&&Min[i]<Min[j]){
53 cnt[Max[j]+j]++;
54 j--;
55 }
56 while(k>j&&Max[k]<Max[i]){
57 cnt[Max[k]+k]--;
58 k--;
59 }
60 ans+=cnt[Min[i]+i];
61 }
62 while(k>j){
63 cnt[Max[k]+k]--;
64 k--;
65 }
66 }
67 int main(){
68 scanf("%d",&n);
69 for(int i=1;i<=n;i++){
70 int x,y;
71 scanf("%d%d",&x,&y);
72 a[x]=y;
73 }
74 Divi(1,n);
75 printf("%d",ans);
76 return 0;
77 }