【BZOJ4237】 稻草人 CDQ分治+单调栈
题目描述
JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典。
有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地。和启示中的一样,田地需要满足以下条件:
田地的形状是边平行于坐标轴的长方形;
左下角和右上角各有一个稻草人;
田地的内部(不包括边界)没有稻草人。
给出每个稻草人的坐标,请你求出有多少遵从启示的田地的个数
简述 求\(n\)个点组成的内部不含其它点的矩形有多少
Solution
为什么要专门记录这个简单的\(CDQ\)分治+单调栈简单题呢,那是因为这道题脱离了\(CDQ\)分治的模板,转更深刻的探究\(CDQ\)分治解决的问题本质
首先这道题找矩形,就要找其左下角及右上角
我们把被处在右上角的点\(b\)与左下角的点\(a\)形成有效矩形成称为\(b\)控制\(a\)
可理解为,处在左下位置的点会对右上位置的点造成贡献,被控制
我们把点按\(y\)轴排序
按\(y\)来划分上下
上下以\(x\)来归并排序(结果就是,\([ql,mid]\)的\(y\)都比\([mid+1,qr]\)的\(y\)要小,但区间内有且仅有\(x\)有序)
如图,\([ql,mid]\)为上面,\([mid+1,qr]\)为下面

因此\(a\)来自下方,\(b\)来自上方
\(Ans_b\)=(在\(b\)左侧可以成为左下角的\(a\)-被\(b\)左边的管并且不会被\(b\)管的\(a\))
对在\(b\)左侧可以成左下角的\(a\)
现在证明:如果\(a\)是满足条件的,则在\(a\)右上侧的\(a'\)就是无效的
分两种情况


因此对\(a\)我们维护一个\(y\)值单调递减的单调栈
每次维护\(x<b_x\)的单调栈即可
for(;q[j].x<q[i].x&&j<=mid;++j){//下,保存的是所有可以成为左下角的点
while(topmax&&q[j].y>q[stmax[topmax]].y)--topmax;
stmax[++topmax]=j;
}
被\(b\)左边的管并且不会被\(b\)管的\(a\)
现在证明:在\(b\)左下侧的\(b'\)是不会影响\(b\)管辖范围的

因此对\(b\)我们维护一个\(y\)值单调递增的单调栈
每一次
\(Ans_b\)=(在\(b\)左侧可以成为左下角的\(a\)-被\(b\)左边的管并且不会被\(b\)管的\(a\))
=\(topmax-b\)的单调栈的前栈顶管辖的\(a\)个数
实现时用二分即可找到前栈顶管辖的最后一个\(a\)位置减掉即可
inline int Find(void){
re int l=1,r=topmax,mid,ans=0;
while(l<=r){
mid=(l+r)>>1;
if(q[stmax[mid]].x<q[stmin[topmin-1]].x){ans=mid;l=mid+1;}
else r=mid-1;
}
return ans;
}
inline void CDQ(re int ql,re int qr){
re int i,j,l,r,t,mid=(ql+qr)>>1;
if(ql==qr)return ;
CDQ(ql,mid);CDQ(mid+1,qr);
j=ql;topmin=topmax=0;
for(i=mid+1;i<=qr;++i){//上,保存的是所有可以影响之后右上角点的(左下角点的个数)的点
while(topmin&&q[i].y<q[stmin[topmin]].y)--topmin;
stmin[++topmin]=i;
for(;q[j].x<q[i].x&&j<=mid;++j){//下,保存的是所有可以成为左下角的点
while(topmax&&q[j].y>q[stmax[topmax]].y)--topmax;
stmax[++topmax]=j;
}
ans+=topmax-Find();
}
l=t=ql;r=mid+1;
while(l<=mid&&r<=qr){
if(q[l].x<q[r].x)tmp[t++]=q[l++];
else tmp[t++]=q[r++];
}
while(l<=mid)tmp[t++]=q[l++];
while(r<=qr)tmp[t++]=q[r++];
for(i=ql;i<=qr;++i)q[i]=tmp[i];
}
放一个示意图(一定要手推)

【BZOJ4237】 稻草人 CDQ分治+单调栈的更多相关文章
- bzoj4237: 稻草人 cdq分治 单调栈
目录 题目链接 题解 代码 题目链接 bzoj4237: 稻草人 题解 暴力统计是n^2的 考虑统计一段区间对另一端的贡献 对于y值cdq分治,降调一维 对于当前两个分治区间统计上面那部分对下面那部分 ...
- 【BZOJ4237】稻草人 cdq分治+单调栈+二分
[BZOJ4237]稻草人 Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田 ...
- bzoj 4237 稻草人 - CDQ分治 - 单调栈
题目传送门 传送点I 传送点II 题目大意 平面上有$n$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...
- [BZOJ4237]稻草人:CDQ分治+单调栈
分析 按\(y\)排序后CDQ分治,可以发现每个点可以影响的是\(x\)坐标的一段区间,可以使用扫描线+单调栈,在单调栈上二分即可解决,时间复杂度\(O(n \log^2 n)\). 通过归并排序可以 ...
- Loj#2880-「JOISC 2014 Day3」稻草人【CDQ分治,单调栈,二分】
正题 题目链接:https://loj.ac/problem/2880 题目大意 给出平面上的\(n\)个点,然后求有多少个矩形满足 左下角和右上角各有一个点 矩形之间没有其他点 \(1\leq n\ ...
- $bzoj4237$稻草人 $cdq$分治
正解:$cdq$分治 解题报告: 传送门$QwQ$ $umm$总感觉做过这题的亚子,,,? 先把坐标离散化,然后把所有点先按$x$排序$QwQ$,然后用类似平面最近点对的方法,先分别解决$mid$两侧 ...
- [BZOJ4237]稻草人(CDQ分治)
先按y排序,二分,两边递归下去,然后处理下半部分对上半部分的贡献,即左下点在下半部分,右上点在上半部分的合法矩形个数. 两个部分均按x排序,枚举右上点p,则左下点需要满足: 1.横坐标大于上半部分纵坐 ...
- 【bzoj4237】稻草人 分治+单调栈+二分
题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条件: ...
- BZOJ4237 JOISC2014 稻草人 CDQ分治、单调栈
传送门 题意:给出平面上$N$个点,求满足以下两个条件的矩形:①左下角与右上角各有一个点:②矩形内部没有点.$N \leq 2 \times 10^5$,所有数字大于等于$0$,保证坐标两两不同 最开 ...
随机推荐
- Data-Structure-Notes
Data Structure Notes Chapter-1 Sorting Algorithm Selection Sorting: /* * Selection Sort */ template& ...
- C语言的变参列表 va_list
1. va_list的基本原理和用法 #include<stdio.h> #include<stdarg.h> void func(int i,char *ch,...){ / ...
- 唯一ID生成器--雪花算法
在微服务架构,分布式系统中的操作会有一些全局性ID的需求,所以我们不能用数据库本身的自增功能来产生主键值,只能由程序来生成唯一的主键值.我们采用的是twitter的snokeflake(雪花)算法. ...
- Windows 上的应用程序在运行期间可以给自己改名(可以做 OTA 自我更新)
原文:Windows 上的应用程序在运行期间可以给自己改名(可以做 OTA 自我更新) 程序如何自己更新自己呢?你可能会想到启动一个新的程序或者脚本来更新自己.然而 Windows 操作系统允许一个应 ...
- SQLServer更新数据库每行一个随机数
代码: ) DECLARE user_extension_cursor CURSOR FOR SELECT UserCode FROM Users OPEN user_extension_cursor ...
- Kafka 生产者、消费者与分区的关系
背景 最近和海康整数据对接, 需要将海康产生的结构化数据拿过来做二次识别. 基本的流程: 海康大数据 --> kafka server --> 平台 Kafka 的 topic 正常过车 ...
- 【转载】C#中使用int.Parse方法将字符串转换为整型Int类型
在C#编程过程中,很多时候涉及到数据类型的转换,例如将字符串类型的变量转换为Int类型就是一个常见的类型转换操作,int.Parse方法是C#中专门用来将字符串转换为整型int的,int.Parse方 ...
- html5的基本介绍
前言 (1)什么是HTML? 指超文本标记语言(Hyper Text Markup Language); 是用来描述网页的一种语言: 不是编程语言,是一种标记语言: (更多详细内容,百度:https: ...
- Falsk框架 Session 与 Flask-Session
目录 Cookie 与 Session 简单了解 Falsk 中 Session 的保管机制 相关的配置 使用 Flask-Session 三方组件 基础练习题 Cookie 与 Session 简单 ...
- Linux目录结构说明
文件系统层级标准(filesystem hierarchy standard,FHS). http://www.pathname.com/fhs/pub/fhs-2.3.html 以下是对这些目录的解 ...