题面

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. 惊喜Skr人,Istio的创始人Shriram Rajagopalan手把手教你如何使用Istio

    Shriram与来自Google.Lyft.IBM和其他公司的社区贡献者们一起并肩作战,积极地向Istio和Envoy项目作贡献.同时,Shriram是IBM的Amalgam8项目的创始成员之一.目前 ...

  2. Python Road

    引子 雁离群兮不知所归,路遥远兮吾将何往   Python Road[第一篇]:Python简介 Python Road[第二篇]:Python基本数据类型 Python Road[第三篇]:Pyth ...

  3. jenkins--Jenkins+Git+coding+maven 实现自动化测试持续集成

    1.打开Jenkins官网,下载jenkins.war https://jenkins.io/download/ 2.将该war包直接放置到Tomcat的webapp下. 3.查看自己Tomcat的端 ...

  4. TPO-11 C1 Use the gym pass

    TPO-11 C1 Use the gym pass 第 1 段 1.Listen to a conversation between a student and a university emplo ...

  5. python切片技巧

    写一个程序,打印数字1到100,3的倍数打印“Fizz”来替换这个数,5的倍数打印“Buzz”,对于既是3的倍数又是5的倍数的数字打印“FizzBuzz” for x in range(101): p ...

  6. SQL语言重点学习

    数据库的操作任务通常包括以下几个方面: 1.查询数据. 2.在表中插入,修改和删除记录. 3.建立,修改和删除数据对象. 4.控制对数据和数据对象的读写. 5.保证数据库一致性和完整性. SQL语言学 ...

  7. 解决ssh_exchange_identification:read connection reset by peer 原因

    服务器改了密码,试过密码多次后出现: ssh_exchange_identification: read: Connection reset by peer 可以通过ssh -v查看连接时详情 Ope ...

  8. cygwin—excellent work!

    使用cygwin的好处在于可以避免直接使用linux同时又能最大限度的节省资源,共享windows的资源. 安装cygwin 安装安简单,当然,你首先需要使用163或者国内或者亚洲比较好的镜像作为下载 ...

  9. LeetCode 386——字典序排数

    1. 题目 2. 解答 2.1 方法一 假设返回 118 以内数的字典顺序,则为 1,10,100,101,102,...,109,11,110,111,112,...,118,12,13,....根 ...

  10. day-20 tensorflow持久化之入门学习

    如果不对模型参数进行保存,当训练结束以后,模型也在内存中被释放,下一轮又需要对模型进行重新训练,有没有一种方法,可以利用之前已经训练好的模型参数值,直接进行模型推理或者继续训练?这里需要引入一个数据之 ...