题解:
cdq分治
二位变成一维
二分一下
代码:
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=200011; int n,Stack[N],top,Stack2[N],tail; LL ans; struct node{int x,y;}a[N]; bool cmpx(node q,node qq){return q.x<qq.x;} bool cmpy(node q,node qq){return q.y<qq.y;} void solve(int l,int r) { if (l==r) return; sort(a+l,a+r+1,cmpy); int mid=(l+r)>>1; sort(a+l,a+mid+1,cmpx); sort(a+mid+1,a+r+1,cmpx); top=tail=0; int now=l,L,R,pos,mm,cp; for (int i=mid+1;i<=r;i++) { while (top>0&&a[Stack[top]].y>=a[i].y)top--; Stack[++top]=i; while (now<=mid&&a[now].x<a[i].x) { while (tail>0&&a[Stack2[tail]].y<=a[now].y) tail--; Stack2[++tail]=now; now++; } L=1;R=tail;pos=-1;cp=a[Stack[top-1]].x; while (L<=R) { mm=(L+R)>>1; if (a[Stack2[mm]].x>cp) pos=mm,R=mm-1; else L=mm+1; } if (pos!=-1) ans+=tail-pos+1; } solve(l,mid); solve(mid+1,r); } int main() { scanf("%d",&n); for (int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y); a[0].x=a[0].y=-1; solve(1,n); printf("%lld",ans); return 0; }