【BZOJ4237】稻草人 [分治][单调栈]
稻草人
Time Limit: 40 Sec Memory Limit: 256 MB
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
0 0
2 2
3 4
4 3
Sample Output
HINT
Solution
O(n^2)做法很显然,既然这样,我们就使用惯用套路,我们先对 y 进行分治,将上面的点视为右上角的点,下面的视为左下角的点,统计答案。
首先把两部分的点分别按照 x 升序排序。
然后枚举上面的每个点。
显然,约束到它拓展的是 在它左下方最接近的点。
同时,下面的点最近的右上方点约束到点的拓展。
那我们对于上面维护一个 y 递增的单调栈,对下面维护一个 y 递减的单调栈。
枚举到上面的点的时候,把 x 小于它的下面的点加入下面的那个单调栈,然后二分一下可行的位置就可以了。
(显然,只有当下面的x > 上面单调栈倒数第二个点的 x 的时候 才可以被加入答案)
(middle写成了mid调了一个小时!好气呀(╯‵□′)╯︵┻━┻)
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std;
typedef long long s64; const int ONE = ; int get()
{
int res = , Q = ; char c;
while( (c = getchar()) < || c > )
if(c == '-') Q = -;
if(Q) res = c - ;
while( (c = getchar()) >= && c <= )
res = res * + c - ;
return res * Q;
} int n; struct point
{
int x, y;
}a[ONE]; bool cmpx(const point &a, const point &b) {return a.x < b.x;}
bool cmpy(const point &a, const point &b) {return a.y < b.y;} int Stk_down[ONE], Stk_up[ONE];
s64 Ans; void Solve(int l, int r)
{
if(l >= r) return;
int mid = l + r >> ; sort(a + l, a + r + , cmpy);
sort(a + l, a + mid + , cmpx);
sort(a + mid + , a + r + , cmpx); int top_up = , top_down = ;
int now = l; for(int i = mid + ; i <= r; i++)
{
while(top_up > && a[Stk_up[top_up]].y >= a[i].y) top_up--;
Stk_up[++top_up] = i; while(now <= mid && a[now].x <= a[i].x)
{
while(top_down > && a[Stk_down[top_down]].y <= a[now].y) top_down--;
Stk_down[++top_down] = now;
now++;
} int left = , right = top_down, pos = ;
int lx = top_up - > ? a[Stk_up[top_up - ]].x : -; while(left < right - )
{
int middle = left + right >> ;
if(a[Stk_down[middle]].x >= lx)
right = middle;
else
left = middle;
} if(a[Stk_down[left]].x >= lx) pos = left;
else
if(a[Stk_down[right]].x >= lx) pos = right; if(pos) Ans += top_down - pos + ;
} Solve(l, mid), Solve(mid + , r);
} int main()
{
n = get();
for(int i = ; i <= n; i++)
a[i].x = get(), a[i].y = get(); Solve(, n);
printf("%lld", Ans);
}
【BZOJ4237】稻草人 [分治][单调栈]的更多相关文章
- BZOJ4237 稻草人 分治 单调栈
原文链接https://www.cnblogs.com/zhouzhendong/p/8682572.html 题目传送门 - BZOJ4237 题意 平面上有$n(n\leq 2\times 10^ ...
- 【bzoj4237】稻草人 分治+单调栈+二分
题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条件: ...
- 【BZOJ4237】 稻草人 CDQ分治+单调栈
## 题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下 ...
- bzoj4237: 稻草人 cdq分治 单调栈
目录 题目链接 题解 代码 题目链接 bzoj4237: 稻草人 题解 暴力统计是n^2的 考虑统计一段区间对另一端的贡献 对于y值cdq分治,降调一维 对于当前两个分治区间统计上面那部分对下面那部分 ...
- 【BZOJ4237】稻草人 cdq分治+单调栈+二分
[BZOJ4237]稻草人 Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田 ...
- [BZOJ4237]稻草人:CDQ分治+单调栈
分析 按\(y\)排序后CDQ分治,可以发现每个点可以影响的是\(x\)坐标的一段区间,可以使用扫描线+单调栈,在单调栈上二分即可解决,时间复杂度\(O(n \log^2 n)\). 通过归并排序可以 ...
- bzoj 4237 稻草人 - CDQ分治 - 单调栈
题目传送门 传送点I 传送点II 题目大意 平面上有$n$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...
- Loj#2880-「JOISC 2014 Day3」稻草人【CDQ分治,单调栈,二分】
正题 题目链接:https://loj.ac/problem/2880 题目大意 给出平面上的\(n\)个点,然后求有多少个矩形满足 左下角和右上角各有一个点 矩形之间没有其他点 \(1\leq n\ ...
- bzoj4237 稻草人——分治
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4237 分治: 先把所有点按 y 排序,然后二分递归: 对于每个 mid ,计算经过它的矩形的 ...
随机推荐
- bat获取当前日期的前一天
批处理做这样的事情很麻烦,你可以用cscript来实现,比如把下面的内容保存为a.js文件:var d=new Date();d.setTime(d.getTime()-24*3600*1000);v ...
- bash编程2
bash基础编程 前言:条件测试语法有两种书写模式,一种时[expression] ,另外一种是[[exprssion]] ,为了在书写条件测试的过程中,不让大家将两种格式互相混淆,那么在这里只讲一种 ...
- Struts2(七)
以下内容是基于导入struts2-2.3.32.jar包来讲的 1.xml验证 Struts2提供了验证器,实现了通用的验证逻辑.例如: 非空验证器.长度验证器.日期验证器.email验证器等.具体定 ...
- 3dContactPointAnnotationTool开发日志(三四)
今天就是让背景图可以变大变小,变透明度,然后将3d的点投影到图片上,输出2d接触点信息: 可以看到输出了正确的接触点信息: 然后还把空物体的包围盒大小设置为边长为0.1的的正方体,点击选中 ...
- 【Linux】- 简明Vim练习攻略
vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...
- jquery mobiscroll 滑动、滚动
mobiscroll : 滑动选择 2.13.2版本免费,官网(mobiscroll.com)收费 先从官方下载2.13.2体验版下来,查看例子结合官方API学习( http://docs.mobis ...
- idea 复制数据库查询结果,粘贴直接生成insert into 语句
遇到一个场景,需要将数据库查询的结果导入到另外一个数据库中,给我的第一感受是,写程序,从数据库A中获取到数据,在插入到数据库B中. 但是Idea 可以直接复制查询结果,然后粘贴生成insert语句. ...
- 第187天:js基础---常见的Bom对象
BOM(Browser Object Mode)浏览器对象模型,是Javascript的重要组成部分.它提供了一系列对象用于与浏览器窗口进行交互,这些对象通常统称为BOM. 一张图了解一下先 1.wi ...
- Catalan数,括号序列和栈
全是入门的一些东西.基本全是从别处抄的. 栈: 支持单端插入删除的线性容器. 也就是说,仅允许在其一端加入一个新元素或删除一个元素. 允许操作的一端也叫栈顶,不允许操作的一端也叫栈底. 数个箱子相叠就 ...
- BZOJ3712 PA2014Fiolki(kruskal重构树)
对合并过程建树.然后只需要按照时间顺序考虑每个反应就行了,时间顺序根据lca的深度确定. #include<iostream> #include<cstdio> #includ ...