【BZOJ4237】稻草人(CDQ分治,单调栈)

题面

BZOJ

题解

\(CDQ\)分治好题呀

假设固定一个左下角的点

那么,我们可以找到的右下角长什么样子???

发现什么?

在右侧是一个单调递减的东西

那么,对于每一个已经固定好的左下角

我们可以通过单调栈来维护答案

既然只有左下角对右上角会产生贡献

那么,按照\(x\)轴排序之后可以\(CDQ\)分治

\(CDQ\)分治怎么搞?

如果在上面的基础上多了几个点。。

那几根棕色的线链接的连是不能贡献答案的

我们来看看:

这些点的\(y\)轴都在当前这个左下角的右上方那个左下角的上面

(这句话好晕呀。。。)

但是在那么点下面的右上角却是可行的

再来一个点试试。。

这个有点乱。。。

我们发现\(B\)点受到了\(A\)的限制

但是\(C\)点却没有任何限制

我们发现了什么关系?

\(B_x<A_x<C_x\)

也就是说和\(x\)坐标有关系

那么,其实这题已经很显然了

对于\(CDQ\)分治的左右两侧考虑贡献

首先按照\(y\)轴从上往下依次加点

右侧的用单调栈维护,使得\(x\)轴递增

而左侧要反过来,使得\(x\)轴递减

这样的话,每个左侧的点产生的贡献就会被单调栈中的前一个元素所影响

那么用前一个元素在右边的单调栈中二分一下就可以啦

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 222222
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n;
struct Node{int x,y;}p[MAX];
bool operator<(Node a,Node b){return a.x<b.x;}
bool cmp(Node a,Node b){return a.y>b.y;}
ll ans;
int S[MAX],top;
int Q[MAX],H,T;
void CDQ(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
CDQ(l,mid);CDQ(mid+1,r);
sort(&p[l],&p[mid+1],cmp);
sort(&p[mid+1],&p[r+1],cmp);
int h=mid+1;top=0;T=0;
for(int i=l;i<=mid;++i)
{
while(h<=r&&p[h].y>p[i].y)
{
while(top&&p[S[top]].x>p[h].x)--top;
S[++top]=h++;
}
while(T&&p[Q[T]].x<p[i].x)--T;
Q[++T]=i;
if(T==1)
ans+=top;
else
{
int L=1,R=top,pls=top+1;
while(L<=R)
{
int mid=(L+R)>>1;
if(p[S[mid]].y>p[Q[T-1]].y)L=mid+1;
else pls=mid,R=mid-1;
}
ans+=top-pls+1;
}
}
}
int main()
{
n=read();
for(int i=1;i<=n;++i)p[i].x=read(),p[i].y=read();
sort(&p[1],&p[n+1]);
CDQ(1,n);
printf("%lld\n",ans);
return 0;
}

【BZOJ4237】稻草人(CDQ分治,单调栈)的更多相关文章

  1. bzoj4237: 稻草人 cdq分治 单调栈

    目录 题目链接 题解 代码 题目链接 bzoj4237: 稻草人 题解 暴力统计是n^2的 考虑统计一段区间对另一端的贡献 对于y值cdq分治,降调一维 对于当前两个分治区间统计上面那部分对下面那部分 ...

  2. 【BZOJ4237】 稻草人 CDQ分治+单调栈

    ## 题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下 ...

  3. 【BZOJ4237】稻草人 cdq分治+单调栈+二分

    [BZOJ4237]稻草人 Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田 ...

  4. bzoj 4237 稻草人 - CDQ分治 - 单调栈

    题目传送门 传送点I 传送点II 题目大意 平面上有$n$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...

  5. [BZOJ4237]稻草人:CDQ分治+单调栈

    分析 按\(y\)排序后CDQ分治,可以发现每个点可以影响的是\(x\)坐标的一段区间,可以使用扫描线+单调栈,在单调栈上二分即可解决,时间复杂度\(O(n \log^2 n)\). 通过归并排序可以 ...

  6. Loj#2880-「JOISC 2014 Day3」稻草人【CDQ分治,单调栈,二分】

    正题 题目链接:https://loj.ac/problem/2880 题目大意 给出平面上的\(n\)个点,然后求有多少个矩形满足 左下角和右上角各有一个点 矩形之间没有其他点 \(1\leq n\ ...

  7. $bzoj4237$稻草人 $cdq$分治

    正解:$cdq$分治 解题报告: 传送门$QwQ$ $umm$总感觉做过这题的亚子,,,? 先把坐标离散化,然后把所有点先按$x$排序$QwQ$,然后用类似平面最近点对的方法,先分别解决$mid$两侧 ...

  8. [BZOJ4237]稻草人(CDQ分治)

    先按y排序,二分,两边递归下去,然后处理下半部分对上半部分的贡献,即左下点在下半部分,右上点在上半部分的合法矩形个数. 两个部分均按x排序,枚举右上点p,则左下点需要满足: 1.横坐标大于上半部分纵坐 ...

  9. 【bzoj4237】稻草人 分治+单调栈+二分

    题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条件: ...

  10. BZOJ4237 JOISC2014 稻草人 CDQ分治、单调栈

    传送门 题意:给出平面上$N$个点,求满足以下两个条件的矩形:①左下角与右上角各有一个点:②矩形内部没有点.$N \leq 2 \times 10^5$,所有数字大于等于$0$,保证坐标两两不同 最开 ...

随机推荐

  1. Netty ByteBuf梳理

    我们知道,网络数据的基本单位总是字节.Java NIO提供了ByteBuffer作为它的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐. Netty的ByteBuffer替代品是ByteBuf, ...

  2. Mac下安装php5.6/7.1

    安装环境 OS X EI Capitan 10.11.4 Homebrew安装 homebrew是一个类似于ubuntu中apt-get的一个软件管理器,安装比较简单,在命令行中输入如下代码: rub ...

  3. shell 脚本中执行SQL语句 -e "..."

    /usr/local/mysql/bin/mysql -uroot -p123456 -e " use faygo source faygo.sql select * from devqui ...

  4. How to install tcpping on Linux.md

    To install tcptraceroute on Debian/Ubuntu: $ sudo apt-get install tcptraceroute To install tcptracer ...

  5. Spring Boot:Consider defining a bean of type '*.*.*' in your configuration解决方案

    果然不看教程直接使用在遇到问题会懵逼,连解决问题都得搜半天还不一定能帮你解决了... ***************************APPLICATION FAILED TO START*** ...

  6. windows系统下安装node

    最近项目中需要使用到vue框架来实现前后端分离,于是抽时间看了下vue的相关只是,从官网了解到可以使用命令行工具(CLI)来构建应用,于是在本地环境预练了一下 下面这句话摘抄自vue文档: Vue.j ...

  7. Shell脚本的基本流程控制

    if else read -p '请输入分数:' score if [ $score -lt 60 ]; then echo '60分以下' elif  [ $score -lt 70 ]; then ...

  8. HttpClient读取数据乱码的解决方案

    博主是一个近十年的老书虫了,从高中那会儿就开始看网络小说.每天半天看晚上看啊,终于眼睛也近视了,成绩也下降了(....好像说远了) 最近在追辰东的<圣墟>,最近写到精彩部分了,一直等更新. ...

  9. 3.3 for 循环

    Python 编程中 for循环用来遍历序列类型的对象,逐一取出序列中的元素值,每取出一个元素值就执行一次循环体,直到元素取完,循环结束.循环体中的代码块可以和序列中的元素值一点关系都没有,因为for ...

  10. hibernate框架基础描述

    在hibernate中,他通过配置文件(hibernate,cfg.xml)和映射文件(...hbm.xml)把对象或PO(持久化对象)映射到数据库中表,然后通过操作持久化对象,对数据库进行CRUD. ...