【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$,保证坐标两两不同 最开 ...
随机推荐
- layui 上传图片 实现过程
layui.user一个页面只能有一个,写多了会实现js效果 上传图片官方文档有很多功能,但是演示的代码只是一个一个功能演示,如果要综合起来js代码不是简单的拼凑,需要放在指定位置,比如下面的限制文件 ...
- Django框架(十)--ORM多对多关联关系三种创建方式、form组件
多对多的三种创建方式 1.全自动(就是平常我们创建表多对多关系的方式) class Book(models.Model): title = models.CharField(max_length=32 ...
- java之hibernate之组合主键映射
1.在应用中经常会有主键是由2个或多个字段组合而成的.比如成绩表: 第一种方式:把主键写为单独的类 2.类的设计:studentId,subjectId ,这两个主键是一个组件.所以可以采用组件映射的 ...
- Python进阶(九)----json模块, pickle模块, os模块,sys模块,hashlib模块
Python进阶----json模块, pickle模块, os模块,sys模块,hashlib模块 一丶序列化模块 什么是序列化: 将一种数据结构,转换成一个特殊的序列(特殊字符串,用于网络传输 ...
- Java项目之查询后分页
一.Jsp页面: <%@ page language="java" contentType="text/html; charset=UTF-8" page ...
- JAVA导出excel 直接弹出下载框
转自:https://blog.csdn.net/qq_38423105/article/details/80782283 效果展示: 1.首先准备jar包 <dependency> ...
- c语言学习目标
运行c语言环境codeblocks. codeblocks的安装: 安装地址:http://www.codeblocks.org/downloads/26 codeblocks-16.01mingw- ...
- EF执行存储过程(转载)
https://blog.csdn.net/xiaouncle/article/details/82914255 相关文章: https://www.cnblogs.com/Coder-ru/arch ...
- day 03 预科
目录 什么是变量: 变量的组成 变量的风格 1.驼峰体 2.下划线 变量名的组成规范 注释的作用 turtle库的简单使用 什么是变量: 1.是变化的量. 2.变:现实世界中的状态是会发生改变的. 3 ...
- Linux 常见 RAID 及软 RAID 创建
RAID可以大幅度的提高磁盘性能,以及可靠性,这么好的技术怎么能不掌握呢!此篇介绍一些常见RAID,及其在Linux上的软RAID创建方法. mdadm 创建软RAID mdadm -C -v /de ...