#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; int n,cnt,ans,hash[100001],tr[100001];//hash储存离散化前的值 struct point{int x,y;}a[100001]; struct seg{int k,x,y,r;}s[1000001]; //横线时x表示左端点,r表示右端点,y表示纵坐标。 //竖线时表示点(x,y),k=1表示是下端点,k=-1表示是上端点,r没用。 inline bool cmp1(point a,point b){ if(a.x==b.x)return a.y<b.y; else return a.x<b.x; }//将点按x排序 inline bool cmp2(point a,point b){ if(a.y==b.y)return a.x<b.x; return a.y<b.y; }//将点按y排序 inline bool cmp3(seg a,seg b){ if(a.y==b.y)return a.k<b.k; return a.y<b.y; }//将线按y排序 int find(int x){//进行离散化处理 int l=1,r=n; while(l<=r){ int mid=(l+r)>>1; if(hash[mid]<x)l=mid+1; else if(hash[mid]>x)r=mid-1; else return mid; } } void insert(int k,int l,int r,int y){ //k=0时表示插入一条[l,r]的纵坐标为y的横线 //k=1时表示插入点(find(y),l)和点(find(y),r),表示一条竖线 if(!k){ s[++cnt].x=find(l);s[cnt].r=find(r);s[cnt].y=y; } else{ s[++cnt].x=find(y);s[cnt].y=l;s[cnt].k=1; s[++cnt].x=find(y);s[cnt].y=r;s[cnt].k=-1; } } void build(){ sort(a+1,a+n+1,cmp1); for(int i=2;i<=n;i++) if(a[i].x==a[i-1].x)//找到一条竖线 insert(1,a[i-1].y,a[i].y,a[i].x); sort(a+1,a+n+1,cmp2); for(int i=2;i<=n;i++) if(a[i].y==a[i-1].y) insert(0,a[i-1].x,a[i].x,a[i].y); } int lowbit(int x){ return x&(-x); } void update(int x,int y){ while(x<=n){ tr[x]+=y; x+=lowbit(x); } } int askl(int x){ int s=0; while(x){ s+=tr[x]; x-=lowbit(x); } return s; } int ask(int l,int r){ return askl(r)-askl(l); } void work(){ for(int i=1;i<=cnt;i++){ if(!s[i].k)ans+=ask(s[i].x,s[i].r); else update(s[i].x,s[i].k); } } void init(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i].x,&a[i].y); hash[i]=a[i].x; } sort(hash+1,hash+n+1); build(); sort(s+1,s+cnt+1,cmp3); } int main(){ init(); work(); printf("%d",ans+n); return 0; }