题面

BZOJ题面

思路

半平面交代码讲解戳这里,用的就是这道题

我们射箭的函数形如$y=Ax^2+Bx$

考虑每一个靶子$(x_0,y_1,y_2)$,实际上是关于$A,B$的不等式限制条件

我们只要求出有没有$(A,B)$满足所有$2*n$个限制条件就可以了

考虑一个限制条件$y_1\leq Ax_0^2+Bx_0\leq y_2$

把一个$x_0$除过去,可以得到$B$关于$A$的半平面两个:

$B\geq -x_0A+\frac{y_1}{x_0}$

$B\leq -x_0A+\frac{y_2}{x_0}$

实际上就是两条平行线(不过这个性质没什么用)

显然题目具有二分性,二分答案,每次对于前一部分的所有限制做半平面交即可

技巧

可以先把所有半平面(包括四个外围限制)排个序,然后每次二分求解的时候扫一遍提取出本次求解需要的

半平面交如果可以剩下一个点(本题是可以的),需要在判断点是否在线的右边的函数里面修改条件,不能包括点在线上的情况

半平面交模板参考这道题:所有线段有向,从a到b,半平面交求所有有向线段的左边半平面的交,外围框子是逆时针的

同一份半平面交里面的所有点线关系都是一致的(都是左边or右边)

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<cmath>
#define eps 1e-18
#define inf 1e33
#define ll long long
using namespace std;
inline int read(){
int re=0,flag=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') flag=-1;
ch=getchar();
}
while(isdigit(ch)) re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
inline bool sign(long double x){
if(x>eps) return 1;
if(x<-eps) return -1;
return 0;
}
int n,m;
struct node{
long double x,y;
node(long double xx=0.0,long double yy=0.0){x=xx;y=yy;}
inline friend node operator +(const node &a,const node &b){return node(a.x+b.x,a.y+b.y);}
inline friend node operator -(const node &a,const node &b){return node(a.x-b.x,a.y-b.y);}
inline friend node operator *(const node &a,const long double &b){return node(a.x*b,a.y*b);}
inline friend long double operator *(const node &a,const node &b){return a.x*b.y-a.y*b.x;}
inline friend long double operator /(const node &a,const node &b){return a.x*b.x+a.y*b.y;}
inline friend long double slope(const node &a,const node &b){return atan2l(a.y-b.y,a.x-b.x);}
}rt[300010];
struct seg{
node a,b;long double k;int id;
seg(node aa=node(),node bb=node()){a=aa;b=bb;k=slope(aa,bb);id=0;}
seg(node aa,node bb,long double kk){a=aa;b=bb;k=kk;id=0;}
inline friend bool operator <(const seg &a,const seg &b){return a.k<b.k;}
inline friend node cross(const seg &a,const seg &b){
long double v1=(a.a-b.b)*(a.b-b.b);
long double v2=(a.a-b.a)*(a.b-b.a);
return b.b+(b.a-b.b)*(v1/(v1-v2));
}
inline friend bool right(const node &a,const seg &b){
return ((a-b.b)*(a-b.a))>eps;
}
}lis[300010],a[300010],q[300010];
inline bool solve(int lim){
int i,head=1,tail=0,flag,tot=0;
for(i=1;i<=m;i++) if(lis[i].id<=lim) a[++tot]=lis[i];
for(i=1;i<=tot;i++){
flag=0;
while((head<=tail)&&(!sign(a[i].k-q[tail].k))){
if(right(q[tail].a,a[i])) tail--;
else{flag=1;break;}
}
if(flag) continue;
while(head<tail&&right(rt[tail],a[i])) tail--;
while(head<tail&&right(rt[head+1],a[i])) head++;
q[++tail]=a[i];
if(head<tail) rt[tail]=cross(q[tail],q[tail-1]);
}
while(head<tail&&right(rt[tail],q[head])) tail--;
while(head<tail&&right(rt[head+1],q[tail])) head++;
return (tail-head>1);
}
const long double pi=acos(-1.0);
int main(){
n=read();int i;long double x1,y1,y2;
m=n<<1;
for(i=1;i<=n;i++){
x1=read();y1=read();y2=read();
lis[i]=seg(node(0,y1/x1),node(1,y1/x1-x1));
lis[i+n]=seg(node(1,y2/x1-x1),node(0,y2/x1));
lis[i].id=lis[i+n].id=i;
}
lis[++m]=seg(node(-1e12,1e12),node(-1e12,-1e12),pi/2.0);
lis[++m]=seg(node(1e12,1e12),node(-1e12,1e12),0);
lis[++m]=seg(node(1e12,-1e12),node(1e12,1e12),-pi/2.0);
lis[++m]=seg(node(-1e12,-1e12),node(1e12,-1e12),pi);
sort(lis+1,lis+m+1);
int l=1,r=n,mid;
while(l<r){
mid=(l+r)>>1;mid++;
if(solve(mid)) l=mid;
else r=mid-1;
}
cout<<l<<'\n';
}

[HNOI2012][BZOJ2732] 射箭 [二分+半平面交]的更多相关文章

  1. 【BZOJ2732】【HNOI2012】射箭 二分+半平面交

    此题重点在卡精度!!! 本地已经下载数据测试并通过了,然而$B$站上还是$WA$的,可能是$CPU$对于$long\ double$ 的资瓷不一样. 此题答案显然是可以二分出来的,设当前要监测是否能射 ...

  2. UVa 1475 (二分+半平面交) Jungle Outpost

    题意: 有n个瞭望塔构成一个凸n边形,敌人会炸毁一些瞭望台,剩下的瞭望台构成新的凸包.在凸多边形内部选择一个点作为总部,使得敌人需要炸毁的瞭望塔最多才能使总部暴露出来.输出敌人需要炸毁的数目. 分析: ...

  3. poj 3525Most Distant Point from the Sea【二分+半平面交】

    相当于多边形内最大圆,二分半径r,然后把每条边内收r,求是否有半平面交(即是否合法) #include<iostream> #include<cstdio> #include& ...

  4. 二分+半平面交——poj1279

    /* 二分距离,凸包所有边往左平移这个距离,半平面交后看是否还有核存在 */ #include<iostream> #include<cstring> #include< ...

  5. POJ3525:Most Distant Point from the Sea(二分+半平面交)

    pro:给定凸多边形,求凸多边形内的点到最近边界的最远距离. sol:显然是二分一个圆,使得圆和凸多边形不相交,但是这样很难实现. 由于是凸多边形,我们可以把二分圆转化为二分凸多边形的移动. 如果每一 ...

  6. POJ 3525/UVA 1396 Most Distant Point from the Sea(二分+半平面交)

    Description The main land of Japan called Honshu is an island surrounded by the sea. In such an isla ...

  7. POJ3525-Most Distant Point from the Sea(二分+半平面交)

    Most Distant Point from the Sea Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3955   ...

  8. 【bzoj2732】[HNOI2012]射箭 二分+半平面交

    题目描述 给出二维平面上n个与y轴平行的线段,求最大的k,使得存在一条形如$y=ax^2+bx(a<0,b>0)$的抛物线与前k条线段均有公共点 输入 输入文件第一行是一个正整数N,表示一 ...

  9. poj3525Most Distant Point from the Sea(半平面交)

    链接 求凸多边形内一点距离边最远. 做法:二分+半平面交判定. 二分距离,每次让每条边向内推进d,用半平面交判定一下是否有核. 本想自己写一个向内推进..仔细一看发现自己的平面交模板上自带.. #in ...

随机推荐

  1. 利用反射获取Model值

    public ActionResult Base(UserModel Model) { Model.Tel = string.Format("{0}-{1}", Model.Are ...

  2. Mate20兼容性如何?WeTest带你抢先测!

    自从九月份 iPhone XS 系列发布后,WeTest团队迅速入库了iPhone XS和iPhone XR设备,十月份国内巨头华为也重磅推出了一款“Mate 20”设备,让下半年的国内手机市场又热闹 ...

  3. lesson 17 The longest suspension bridge in the world

    lesson 17 The longest suspension bridge in the world agreeable adj. 令人愉快的:适合的 = pleasant be located ...

  4. VMWare Workstation新装CentOS 7无法联网解决办法

    按照这位博主的方法成功解决:http://blog.csdn.net/deniro_li/article/details/54632949

  5. gitolite 丢失管理密钥/访问权限 解决办法

    登录到服务器. 使用完整路径克隆管理员仓库: git clone $HOME/repositories/gitolite-admin.git temp cd gitolite-admin/conf v ...

  6. 90 [LeetCode] Subsets2

    Given a collection of integers that might contain duplicates, nums, return all possible subsets (the ...

  7. HADOOP/HDFS Essay

    HDFS架构 the core of HADOOP/distributed systems is storeage(HDFS) and resource manager(YARN) for compu ...

  8. 共识算法 pos,Dpos

    在之前讲解了比特币中的共识算法pow(proot of work),我们先来简单的回顾一下. 新的交易将会广播给所有节点. 每个节点将都会讲新的交易收集到一个区块中. 每个节点都在为其区块收集困难的工 ...

  9. Ext JS 6学习文档-第4章-数据包

    Ext JS 6学习文档-第4章-数据包 数据包 本章探索 Ext JS 中处理数据可用的工具以及服务器和客户端之间的通信.在本章结束时将写一个调用 RESTful 服务的例子.下面是本章的内容: 模 ...

  10. Python中的__future__

    在Python中,你如果在某一个版本的Python想使用未来版本中的功能,可以使用如下语法实现: from __future__ import futurename 这条语句必须放在module文件的 ...