[bzoj1007][HNOI2008]水平可见直线_单调栈
水平可见直线 bzoj-1007 HNOI-2008
题目大意:给你n条直线,为你从上往下看能看见多少跳直线。
注释:能看见一条直线,当且仅当这条直线上存在一条长度>0的线段使得这条线段上方没有其他直线,$1\le n 5\cdot 10^4$。
想法:神题qwq。看见网上的做法突然有一种学计算几何的冲动,直到看见一篇大神的blog说用单调栈做?这题困难其实就困难在如何规定两条直线之间本不存在的单调性。用单调栈就是讲即将进栈元素不断和栈顶比较,然后弹来弹去最后剩下的都是可见的。不容易难想到:将直线先按斜率排序。如果两直线斜率相等那么截距小的那个自然直接gg。

显然,当待入栈直线和栈顶直线的交点直接决定了栈顶直线是否仍有存在的意义。如果$l_3$和$l_2$的交点在x左侧,那么显然,$l_2$就可以滚犊犊了。以此类推,即可。
最后,附上丑陋的代码... ...
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1000010
using namespace std;
struct Node
{
double k,b;
int id;
}l[N];
inline bool cmp(Node a,Node b)
{
if(a.k!=b.k) return a.k<b.k;
return a.b>b.b;
}
double getpos(Node a,Node b)
{
return (b.b-a.b)/(a.k-b.k);
}
int s[N];
bool ans[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&l[i].k,&l[i].b);
l[i].id=i;
}
sort(l+1,l+1+n,cmp);
int top=1;
s[1]=1;
for(int i=2;i<=n;i++)
{
if( l[i].k-l[i-1].k < 1e-8) continue;
while(top > 1&& getpos(l[i],l[s[top]]) <= getpos(l[s[top]],l[s[top-1]]) ) top--;
s[++top]=i;
}
for(int i=1;i<=top;i++) ans[l[s[i]].id]=1;
for(int i=1;i<=n;i++)
{
if(ans[i])
{
printf("%d ",i);
}
}
puts("");
return 0;
}
小结:对于这种问题将已知的元素排序,并将它们强行化作单调的情况,是不必要但可行的。
[bzoj1007][HNOI2008]水平可见直线_单调栈的更多相关文章
- 【BZOJ1007】水平可见直线(单调栈)
[BZOJ1007]水平可见直线(单调栈) 题解 Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的 ...
- BZOJ_1007_ [HNOI2008]_水平可见直线_(单调栈+凸包)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1007 给出一些直线,沿着y轴从上往下看,能看到多少条直线. 分析 由于直线相交,会遮挡住一些直 ...
- bzoj 1007 [HNOI2008]水平可见直线(单调栈)
1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5120 Solved: 1899[Submit][Sta ...
- 【洛谷 P3194】 [HNOI2008]水平可见直线 (单调栈)
题目链接 把线段以斜率为第一关键字,截距为第二关键字升序排序. 然后维护一个单调栈,保证栈中两两线段的交点的\(x\)坐标单调上升就行了.栈中的线段即为所求. #include <cstdio& ...
- _bzoj1007 [HNOI2008]水平可见直线【单调栈】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1007 按斜率排序,去掉斜率相同时,截距较小的直线(即只保留该斜率下截距最大的直线).若当前直 ...
- BZOJ1007: [HNOI2008]水平可见直线(单调栈)
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8638 Solved: 3327[Submit][Status][Discuss] Descripti ...
- bzoj1007: [HNOI2008]水平可见直线 单调栈维护凸壳
在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.例如,对于直线:L1:y=x; L2:y=-x; L3 ...
- bzoj1007 [HNOI2008]水平可见直线——单调栈
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1007 可以把直线按斜率从小到大排序,用单调栈维护,判断新直线与栈顶的交点和栈顶与它之前直线的 ...
- 【BZOJ1007】【HNOI2008】水平可见直线 几何 单调栈
题目大意 给你\(n\)条直线\(y=kx+b\),问你从\(y\)值为正无穷大处往下看能看到那些直线. \(1\leq n\leq 500000\) 题解 如果对于两条直线\(l_i,l_j\),\ ...
随机推荐
- Gym - 100162G 2012-2013 Petrozavodsk Winter Training Camp G. Lyndon Words 暴力枚举
题面 题意:如果一个字符串的最小表示法是他自己,他就是一个Lyndon Word. 例如 aabcb 他的循环串有 abcba bcbaa cbaab baabc 其中字典序最小的是他自己 现在给 ...
- Gym - 100920E 2010-2011 OpenCup IX Onsite, II Yandex Summer School E.Paint 状压DP
题面 题意:给你n(20)个点,m(40条边),让你给每条边染一种颜色,白色0元,红色2元,蓝色1元,现在要保证每一条白边相邻的有一条红边,问至少花多少 题解:刚开始想的时候,好像觉得只用染红色和白色 ...
- [App Store Connect帮助]二、 添加、编辑和删除用户(5)创建一个沙盒测试员帐户
如果您的 App 使用了 App 内购买项目或 Apple Pay,您可以在 App Store Connect 中创建沙盒测试员帐户,以便您向用户提供该 App 前,可以使用该帐户在测试环境中运行您 ...
- [Swift通天遁地]五、高级扩展-(1)快速检测设备属性:版本、类型、屏幕尺寸
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Idea使用Maven搭建SpringMVC的HelloSpringMvc并配置插件Maven和Jetty
这篇博文只是纯粹的搭建一个SpringMVC的项目, 并不会涉及里面配置文件该写些什么. 只是纯粹的搭建一个初始的Hello SpringMVC的项目. 废话不多说,上图. 1. 打开IDEA 并且 ...
- group by 和 select
group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面.
- 【知识总结】快速傅里叶变换(FFT)
这可能是我第五次学FFT了--菜哭qwq 先给出一些个人认为非常优秀的参考资料: 一小时学会快速傅里叶变换(Fast Fourier Transform) - 知乎 小学生都能看懂的FFT!!! - ...
- ACM_Repeating Characters
Repeating Characters Time Limit: 2000/1000ms (Java/Others) Problem Description: For this problem, yo ...
- setjmp和longjmp函数
关于setjmp函数和longjmp函数有话要说,是UNIX高级环境变成看到了10.10信号那章用到了,研究一下,这里作为补充. setjmp(jmp_buf env_buf) 函数可以将当前的运行环 ...
- Excel文件导入导出
/** * 导入Excel文件数据 * * @param file 将要导入的Excel文件 * @param fileCheckKeyWord 用于判断导入文件是否 ...