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;
    }
    

      

  • 相关阅读:
    mysql递归层次查询
    mybatis+spring事务
    浅谈数据库表的分割技术(水平、垂直、库表散列)(引用)
    高并发的常见思维
    jee websocket搭建总结
    hibernate 多表查询
    jsp作为服务端,ajax请求回应
    排序(2)--希尔,快速,归并
    排序(1)--冒泡,插入,选择
    Java反射基础
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/8682572.html
Copyright © 2011-2022 走看看