4237: 稻草人
我们按照y分治,分成上下两部分,然后将x排序,用单调栈维护个数就可以了。
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=200005;
int n,stk1[MAXN],Top1,stk2[MAXN],Top2;long long Ans;
struct xcw{int x,y;}a[MAXN];
bool cmpy(xcw x,xcw y){return x.y<y.y;}
bool cmpx(xcw x,xcw y){return x.x<y.x;}
void Work(int L,int mid,int R){
Top1=Top2=0;
for(int i=mid+1,j=L;i<=R;i++){
while(Top1&&a[stk1[Top1]].y>=a[i].y) Top1--;
stk1[++Top1]=i;
for(;j<=mid&&a[j].x<a[i].x;j++){
while(Top2&&a[stk2[Top2]].y<=a[j].y) Top2--;
stk2[++Top2]=j;
}
int l=1,r=Top2,x=a[stk1[Top1-1]].x;
while(l<=r){
int mid=r+l>>1;
if(a[stk2[mid]].x<x) l=mid+1;else r=mid-1;
}
Ans+=Top2-l+1;
}
}
void Solve(int L,int R){
if(L>=R) return;
sort(a+L,a+R+1,cmpy);
int mid=R+L>>1;
sort(a+L,a+mid+1,cmpx);
sort(a+mid+1,a+R+1,cmpx);
Work(L,mid,R);
Solve(L,mid),Solve(mid+1,R);
}
#include<cctype>
int read(){
int ret=0;char ch=getchar();bool f=1;
for(;!isdigit(ch);ch=getchar()) f^=!(ch^'-');
for(; isdigit(ch);ch=getchar()) ret=ret*10+ch-48;
return f?ret:-ret;
}
int main(){
n=read();a[0]=(xcw){-1,-1};
for(int i=1;i<=n;i++) a[i]=(xcw){read(),read()};
Solve(1,n);
printf("%lld\n",Ans);
return 0;
}