题意:裸的二维偏序
直接上CDQ乱搞,或者线段树。。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mid ((l+r)>>1)
const int N=200010;
using namespace std;//CDQ分治+坐标离散化
int a[N],b[N],x[N],y[N],id[N],n;
long long ans;
inline bool cmpf(const int &i,const int &j){//排序x
return x[i]<x[j];
}
inline bool cmps(const int &i,const int &j){//排序y
return y[i]<y[j];
}
inline void cdq(int l,int r,int tx=0,int ty=0){//直接上cdq分治。log_n^2
if(l==r)return;
cdq(l,mid),cdq(mid+1,r);
sort(id+l,id+mid+1,cmps);//
sort(id+mid+1,id+r+1,cmps);//
for(register int i=mid+1,j=l;i<=r;i++){
while(j<=mid&&y[id[j]]<y[id[i]]){//以x排序过,只需要判定y
while(tx>0&&x[a[tx-1]]<x[id[j]])tx--;
a[tx++]=id[j++];
}
while(ty>0&&x[b[ty-1]]>x[id[i]])ty--;
if(ty>0)ans-=lower_bound(a,a+tx,b[ty-1],cmps)-a;//二分查找,求得重复计算的值。
ans+=tx;
b[ty++]=id[i];
}
}
inline void read(int &res){
static char ch;int flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
int main(){
freopen("project.in","r",stdin);
freopen("project.out","w",stdout);
read(n);
for(register int i=1;i<=n;++i)read(x[i]),read(y[i]),id[i]=i;
sort(id+1,id+n+1,cmpf);//总体查找顺序按照x大小排序。
cdq(1,n);
cout<<ans<<endl;
return 0;
}