BZOJ4049][CERC2014]Mountainous landscape-[线段树+凸包+二分]
Description
现在在平面上给你一条折线P1P2P3...Pn。
x坐标是严格单调递增的。对于每一段折线PiPi+1,请你找一个最小的j,使得j>i且走在PiPi+1的人能看到折线PjPj+1上的任意一点。
注意,人的高度无限趋近0但不可忽略。也就是说,请找一条编号最小的折线PiPi+1使得j>i且线段PiPi+1(含端点)与略高于PiPi+1的射线相交。
$2\leq n\leq 10^{5}$
$0\leq x_{i},y_{i}\leq 10^{9}$

Solution
定义折线i为PiPi+1
首先,对于某条折线i,我们无法通过某些公式或比较直接推定它对应的折线j。
遇到这种情况,我们一般先考虑二分。及对于某条折线i,区间[l,r]之间是否有解。
显然这里的判断可以使用凸包。只要该折线与点区间[l,r]之间的凸包上某条边有交点(当然要注意特判,假如折线与凸包交在顶点要算顶点后面的边),则我们可以判定i在[l,r]之间有解。所以用线段树维护凸包,查询时先查询线段树左区间,左区间无解再找右边。在凸包上的判断也可以用二分。(这个的具体判断方法见代码,画个图就好,证明可以利用叉积的几何意义)
我的代码中,区间[l,r]表示的是点集[l,r+1],这样就可以确保最终答案是找到一条折线而不是一个点。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
int n;
struct P{int x,y;
friend P operator-(P a,P b){return P{a.x-b.x,a.y-b.y};}
friend ll operator*(P a,P b){return 1ll*a.x*b.y-1ll*a.y*b.x;}
}p[],st[];int tp=;
int _l[],_r[];
void seg_build(int k,int l,int r)
{
_l[k]=tp+;
for(int i=l;i<=r+;i++)
{
while (tp-_l[k]>&&(st[tp]-st[tp-])*(p[i]-st[tp])>=)
tp--;
st[++tp]=p[i];
}
_r[k]=tp;
if (l==r) return;
int mid=(l+r)/;
seg_build(k<<,l,mid);
seg_build(k<<|,mid+,r);
}
bool check(int k,int id)
{
P a=p[id],v=p[id+]-a;
int l=_l[k],r=_r[k]-,mid;
while (l<r)
{
mid=(l+r)/;
if ((st[mid]-a)*v<(st[mid+]-a)*v) r=mid;
else l=mid+;
}
return (st[l]-a)*v<||(st[l+]-a)*v<;
}
int query(int k,int l,int r,int ask)
{
if (ask<=l)
{
if (!check(k,ask-)) return ;
if (l==r) return l;
}
int mid=(l+r)/;
if (ask<=mid)
{
int re=query(k<<,l,mid,ask);
if (re) return re;
}
return query(k<<|,mid+,r,ask);
}
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
seg_build(,,n-);
for (int i=;i<n-;i++)
printf("%d ",query(,,n-,i+));
printf("");
}
BZOJ4049][CERC2014]Mountainous landscape-[线段树+凸包+二分]的更多相关文章
- BZOJ4049 [Cerc2014] Mountainous landscape
首先对于一个给定的图形,要找到是否存在答案非常简单... 只要维护当然图形的凸包,看一下是否有线段在这条直线上方,直接二分即可,单次询问的时间复杂度$O(logn)$ 现在用线段树维护凸包,即对于一个 ...
- BZOJ 2402 陶陶的难题II (01分数规划+树剖+线段树+凸包+二分)
题目大意:略 一定范围内求最大值,考虑二分答案 设现在选择的答案是$mid$,$max \left \{ \frac{yi+qj}{xi+pj} \right \} \geq mid $ 展开可得,$ ...
- 【BZOJ4552】排序(线段树,二分答案)
[BZOJ4552]排序(线段树,二分答案) 题面 BZOJ 题解 好神的题啊 直接排序我们做不到 怎么维护? 考虑一下,如果我们随便假设一个答案 怎么检验它是否成立? 把这个数设成\(1\),其他的 ...
- luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分)
luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分) Luogu 题外话1: LN四个人切D1T2却只有三个人切D1T1 很神必 我是傻逼. 题外话2: 1e6的数据直接i ...
- BZOJ 3672: [Noi2014]购票( 树链剖分 + 线段树 + 凸包 )
s弄成前缀和(到根), dp(i) = min(dp(j) + (s(i)-s(j))*p(i)+q(i)). 链的情况大家都会做...就是用栈维护个下凸包, 插入时暴力弹栈, 查询时就在凸包上二分/ ...
- 【BZOJ2402】陶陶的难题II 分数规划+树链剖分+线段树+凸包
题解: 首先分数规划是很明显的 然后在于我们如何要快速要求yi-mid*xi的最值 这个是看了题解之后才知道的 这个是斜率的一个基本方法 我们设y=mid*x+z 那么显然我们可以把(x,y)插入到一 ...
- UOJ#7. 【NOI2014】购票 | 线段树 凸包优化DP
题目链接 UOJ #7 题解 首先这一定是DP!可以写出: \[f[i] = \min_{ancestor\ j} \{f[j] + (d[j] - d[i]) * p[i] + q[i]\}\] 其 ...
- [SDOI2014][BZOJ3533] 向量集 [线段树+凸包]
题面 BZOJ传送门 思路 首先当然是推式子 对于一个询问点$(x_0,y_0$和给定向量$(x_1,y_1)$来说,点积这么表达: $A=x_0x_1+y_0y_1$ 首先肯定是考虑大小关系:$x_ ...
- BZOJ3110 [Zjoi2013]K大数查询 树套树 线段树 整体二分 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3110 题意概括 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位 ...
随机推荐
- WebKit由三个模块组成-Webkit模块介绍
2. Webkit 源代码由三大模块组成: 1). WebCore, 2). WebKit, 3). JavaScriptCore. WebCore:排版引擎核心,WebCore包含主要以 ...
- luogu P3381【模板】最小费用最大流
嘟嘟嘟 没错,我开始学费用流了! 做法也是比较朴素的\(spfa\). 就是每一次以费用为权值跑一遍\(spfa\)找到一条最短路,然后把这条道全流满,并把这一次的流量和费用累加到答案上.因此我们需要 ...
- WEB安全 魔术引号及注入类型
一.魔术引号 1. magic_quotes_gpc 变量 什么是魔术引号 Warning本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除.当打开时,所有的 '(单引号),&q ...
- rocketmq搭建
maven参数: mvn -Prelease-all -DskipTests clean install -U
- Shell笔记-03
前面已经讲到,变量名只能包含数字.字母和下划线,因为某些包含其他字符的变量有特殊含义,这样的变量被称为特殊变量. 例如,$ 表示当前Shell进程的ID,即pid,看下面的代码: $echo $$ 运 ...
- lwip IP address handling 关于 IP 地址的 操作 API接口
lwip 2.0.3 IP address handling /** * @file * IP address API (common IPv4 and IPv6) */ 1.u32_t ipadd ...
- react+webpack搭建项目
一.环境准备 ①node ②npm 二.开始搭建 ①使用npm安装create-react-app工具,在cmd命令行中输入: npm install -g create-react-app ②使用命 ...
- linux SVN添加新用户
首先找到用户文件:authz.conf; 用vi 编辑authz.conf文件在develps 后面添加你要添加的用户名:如图: 上图:cheny就是我后面添加上去的用户名 按Esc :wq保存au ...
- Microsoft SQL Server2008安装教程
自己录制的视频,地址https://share.weiyun.com/5VITfph(微云分享,大小52MB,AVI格式) 视频中安装.net framework如果已经安装好了就不需要安装,也可自行 ...
- Linux下ELK环境搭建
一.准备工作 准备3台机器,这样才能完成分布式集群的实验,当然能有更多机器更好: 192.168.3.64(e1) 192.168.3.62 (e2) 192.168.3.63(e3) 角色划分: ...