zoukankan      html  css  js  c++  java
  • BZOJ4237 稻草人 分治 单调栈

    原文链接https://www.cnblogs.com/zhouzhendong/p/8682572.html

    题目传送门 - BZOJ4237

    题意

      平面上有$n(nleq 2 imes 10^5)$个整点(坐标范围在$[0,10^9]$之间)。

      第$i$个点$p_i$的坐标是$(x_i,y_i)$。

      如果有一对点$p_i$和$p_j$,满足$x_i<x_j,y_i<y_j$,而且以这两个点为左下角和右上角所围城的矩形内不包含任何整点(边界上面不算),那么他们对答案的贡献为1。

      求答案。

    题解

      对于$x$坐标分治,然后单调栈解决跨越中线两端的点的贡献即可。

      好像听好写的,不详细介绍了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=200005;
    struct Point{
    	int x,y;
    	void get(){
    		scanf("%d%d",&x,&y);
    	}
    }p[N],q[N];
    int n,Lstack[N],Rstack[N],Ltop,Rtop;
    LL ans=0;
    bool cmpx(Point a,Point b){
    	return a.x<b.x;
    }
    void solve(int xL,int xR,int L,int R){
    	if (L>=R)
    		return;
    	int xmid=(xL+xR)>>1,mid=R;
    	while (mid>=L&&p[mid].x>xmid)
    		mid--;
    	solve(xL,xmid,L,mid);
    	solve(xmid+1,xR,mid+1,R);
    	Ltop=Rtop=0;
    	Lstack[0]=Rstack[0]=0;
    	q[0].y=-1;
    	for (int i=L,l=L,r=mid+1;i<=R;i++)
    		if (r>R||(l<=mid&&p[l].y<=p[r].y)){
    			q[i]=p[l++];
    			while (Ltop>0&&q[Lstack[Ltop]].x<q[i].x)
    				Ltop--;
    			Lstack[++Ltop]=i;
    	/*		int pos=Ltop,y;
    			for (int j=1<<18;j>0;j>>=1)
    				if (pos-j>0&&q[Lstack[pos-j]].x==q[i].x)
    					pos-=j;
    			y=q[Lstack[pos-1]].y+1;
    			pos=Rtop+1;
    			for (int j=1<<18;j>0;j>>=1)
    				if (pos-j>0&&q[Rstack[pos-j]].y>=y)
    					pos-=j;
    			ans+=Rtop-pos+1;*/
    		}
    		else {
    			q[i]=p[r++];
    			while (Rtop>0&&q[Rstack[Rtop]].x>q[i].x)
    				Rtop--;
    			Rstack[++Rtop]=i;
    			int pos=Rtop,y;
    			for (int j=1<<18;j>0;j>>=1)
    				if (pos-j>0&&q[Rstack[pos-j]].x==q[i].x)
    					pos-=j;
    			y=q[Rstack[pos-1]].y+1;
    			pos=Ltop+1;
    			for (int j=1<<18;j>0;j>>=1)
    				if (pos-j>0&&q[Lstack[pos-j]].y>=y)
    					pos-=j;
    			ans+=Ltop-pos+1;
    		}
    	for (int i=L;i<=R;i++)
    		p[i]=q[i];
    }
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		p[i].get();
    	sort(p+1,p+n+1,cmpx);
    	solve(0,1e9,1,n);
    	printf("%lld
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    loj 6035 「雅礼集训 2017 Day4」洗衣服
    BZOJ 3251 树上三角形
    UwrhrQNgRh
    百度之星2018资格赛1002题解
    [CF-676B]PYRAMID OF GLASSES
    【CF-371C】Hamburgers
    洛谷P1012拼数——字符串排序
    位运算详解及应用
    NOIP 2014 Day2 T1 无线网络发射器
    写代码要注意的几点(2)
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ4237.html
Copyright © 2011-2022 走看看