这是一个挺好的题啊
话说应该算cdq分治吧,好久没写过了QwQ
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=200005;
const int MAX=1<<30;
struct qq
{
int x,y;
}s[N];
int n;
bool cmp (qq a,qq b){return a.x<b.x;}
bool cmp1 (qq a,qq b){return a.y>b.y;}
LL ans=0;
qq q1[N],q2[N];//左边 右边的队列
int find (int x,int y)//问现在的队列中比y大的
{
int l=1,r=y;
while (l<=r)
{
int mid=(l+r)>>1;
if (q2[mid].y<=x)
r=mid-1;
else l=mid+1;
}
return r;
}
void solve (int l,int r)//这一段数值的答案
{
if (l>=r) return ;
int mid=(l+r)>>1;
solve(l,mid);solve(mid+1,r);
sort(s+l,s+mid+1,cmp1);sort(s+mid+1,s+1+r,cmp1);
int ed=0,ed1=0,p=mid+1;
q1[0].y=q2[0].y=MAX;
for (int u=l;u<=mid;u++)
{
while (p<=r&&s[p].y>s[u].y)
{
while (ed1!=0&&s[p].x<q2[ed1].x) ed1--;
q2[++ed1]=s[p];
p++;
}
while (ed!=0&&s[u].x>q1[ed].x) ed--;
q1[++ed]=s[u];
int l=find(q1[ed-1].y,ed1)+1;
int r=find(q1[ed].y,ed1);
if (l<=r) ans=ans+(LL)(r-l+1);
}
}
int main()
{
scanf("%d",&n);
for (int u=1;u<=n;u++)
scanf("%d%d",&s[u].x,&s[u].y);
sort(s+1,s+1+n,cmp);
solve(1,n);
printf("%lld\n",ans);
return 0;
}