题意:给你一些点,问由这些点构成右上角和左下角的长方形个数,并且矩形内部不能有其他点
按照
y
y
坐标来分治,分成上下两块
对于某一段我们按照排序,考虑下面的点与上面的点配成的矩形的个数
考虑以当前点
i
i
为右上角,计算下面有多少点能与
i
i
配成矩形
首先要满足这样几种情况
①:
②:
xj>x
x
j
>
x
上面的离
i
i
最近且的点
给张图就是这样的
图中
(x1,y1)
(
x
1
,
y
1
)
就是不合法的点
对于我们来说
(x2,y2)
(
x
2
,
y
2
)
这样的点已经没有用了
但是
(x3,y3)
(
x
3
,
y
3
)
这样的点还是有用的
不难想到我们要在上面维护一个单调上升的栈
如果下面的点
a,b
a
,
b
满足
b
b
在的右上方,那么
a
a
就没用了
所以我们也要在下面维护一个单调下降的栈
对于每一个上面的点,因为是单调的
所以我们可以在下面的栈里二分找到第一个不满足条件②的点
#include<bits/stdc++.h>
#define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
#define go(u) for(register int i=fi[u],v=e[i].to;i;v=e[i=e[i].nx].to)
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char ss[1<<17],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<17,stdin),A==B)?-1:*A++;}
template<class T>inline void sd(T&x){
char c;T y=1;while(c=gc(),(c<48||57<c)&&c!=-1)if(c==45)y=-1;x=c-48;
while(c=gc(),47<c&&c<58)x=x*10+c-48;x*=y;
}
char sr[1<<21],z[20];int C=-1,Z;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
template<class T>inline void we(T x){
if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=2e5+5;
typedef int arr[N];
struct da{int x,y;}a[N],b[N];
int n;arr s1,s2;long long ans;
inline int bf(int x,int L,int R){
int mid=(L+R)>>1;
for(;L+1<R;mid=(L+R)>>1)
if(a[s2[mid]].x<x)L=mid;else R=mid;
return L;
}
void cdq(int L,int R){
if(L==R)return;int mid=(L+R)>>1;
cdq(L,mid),cdq(mid+1,R);
int t1=0,t2=0,i=L,j=mid+1;
for(;j<=R;++j){
while(t1&&a[j].y<a[s1[t1]].y)--t1;
s1[++t1]=j;
for(;i<=mid&&a[i].x<a[j].x;++i){
while(t2&&a[i].y>a[s2[t2]].y)--t2;
s2[++t2]=i;
}
ans+=t2-bf(a[s1[t1-1]].x,0,t2+1);
}i=L,j=mid+1;
fp(k,L,R)b[k]=((i<=mid&&a[i].x<a[j].x)||j>R)?a[i++]:a[j++];
fp(k,L,R)a[k]=b[k];
}
inline bool cpy(const da&a,const da&b){return a.y<b.y;}
int main(){
#ifndef ONLINE_JUDGE
file("s");
#endif
sd(n);
fp(i,1,n)sd(a[i].x),sd(a[i].y);
sort(a+1,a+n+1,cpy);
cdq(1,n);
we(ans);
return Ot(),0;
}