BZOJ4237: 稻草人【CDQ】

8 篇文章 0 订阅

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值