【BZOJ2732】【HNOI2012】射箭 二分+半平面交
此题重点在卡精度!!!
本地已经下载数据测试并通过了,然而$B$站上还是$WA$的,可能是$CPU$对于$long\ double$ 的资瓷不一样。
此题答案显然是可以二分出来的,设当前要监测是否能射穿前$mid$个靶子。
我们发现要穿过第i个靶子,那么$a,b$必须满足$l_i≤ax_i^2+bx_i≤r_i$。
我们简单地转化下式子,我们就可以得到$\dfrac{l_i}{x_i^2}+\dfrac{b}{x_i}≤a≤\dfrac{r_i}{x_i^2}+\dfrac{b}{x_i}$。
我们想象一个以$b$为横坐标,$a$为纵坐标的平面直角坐标系中,这一对约束可以通过两个半平面的交来表示。
不难发现满足射穿前$mid$个靶子的数对$(a,b)$,必然在这$2mid$个半平面的交内。
于是问题就转化为这2$mid$个半平面是否有交(半平面交判定)
时间复杂度:$O(n\ \log\ n)$。
#include<bits/stdc++.h>
#define M 210005
#define D long double
#define eps 1e-20
#define INF 1e15
using namespace std; int dx[M]={},dl[M]={},dr[M]={},m=; struct pt{
D x,y; pt(D X=,D Y=){x=X; y=Y;}
friend pt operator +(pt a,pt b){return pt(a.x+b.x,a.y+b.y);}
friend pt operator -(pt a,pt b){return pt(a.x-b.x,a.y-b.y);}
friend D operator *(pt a,pt b){return a.x*b.y-a.y*b.x;}
void out(){printf("(%.1Lf,%.1Lf)",x,y);}
};
struct line{
pt a,b; D ang; int id;
line(){a=pt(,); b=pt(,);}
line(pt A,pt B,int ID){ id=ID; a=A; b=B;
ang=atan2(b.y-a.y,b.x-a.x);} D getk(){return (b.y-a.y)/(b.x-a.x);}
D getb(){return a.y-a.x*getk();}
friend bool operator <(line a,line b){return a.ang<b.ang;}
friend pt operator *(line a,line b){
D k1=(b.b-a.a)*(a.b-a.a);
D k2=(a.b-a.a)*(b.a-a.a);
D t=k2/(k1+k2);
return pt(b.a.x+t*(b.b.x-b.a.x),b.a.y+t*(b.b.y-b.a.y));
}
}p[M],q[M];
bool inleft(line a,line b,line c){
pt d=a*b;
return (d-c.a)*(c.b-c.a)<=eps;
}
bool solve(int n){
int l=,r=;
for(int i=;i<=m;i++){
if(p[i].id>n) continue;
while(l<r&&(!inleft(q[r-],q[r],p[i]))) r--;
while(l<r&&(!inleft(q[l+],q[l],p[i]))) l++;
q[++r]=p[i];
}
while(l<r&&(!inleft(q[r-],q[r],q[l]))) r--;
while(l<r&&(!inleft(q[l+],q[l],q[r]))) l++;
return r-l>=;
}
int main(){
int n;scanf("%d",&n); if(n<=){printf("%d\n",n); return ;}
for(int i=;i<=n;i++) scanf("%d%d%d",dx+i,dl+i,dr+i);
int l=,r=n;
for(int i=;i<=n;i++){
D L=dl[i],R=dr[i],X=dx[i];
p[++m]=line(pt(,L/(X*X)),pt(,L/(X*X)-/X),i);
p[++m]=line(pt(,R/(X*X)-/X),pt(,R/(X*X)),i);
}
pt a1=pt(INF,INF),a2=pt(-INF,INF),a3=pt(-INF,-INF),a4=pt(INF,-INF);
p[++m]=line(a1,a2,); p[++m]=line(a2,a3,); p[++m]=line(a3,a4,); p[++m]=line(a4,a1,);
sort(p+,p+m+);
while(l<r){
int mid=(l+r+)>>;
if(solve(mid)) l=mid;
else r=mid-;
}
cout<<l<<endl;
}
【BZOJ2732】【HNOI2012】射箭 二分+半平面交的更多相关文章
- 【bzoj2732】[HNOI2012]射箭 二分+半平面交
题目描述 给出二维平面上n个与y轴平行的线段,求最大的k,使得存在一条形如$y=ax^2+bx(a<0,b>0)$的抛物线与前k条线段均有公共点 输入 输入文件第一行是一个正整数N,表示一 ...
- POJ 3525 Most Distant Point from the Sea 二分+半平面交
题目就是求多变形内部一点. 使得到任意边距离中的最小值最大. 那么我们想一下,可以发现其实求是看一个圆是否能放进这个多边形中. 那么我们就二分这个半径r,然后将多边形的每条边都往内退r距离. 求半平面 ...
- 洛谷P3222 [HNOI2012]射箭(计算几何,半平面交,双端队列)
洛谷题目传送门 设抛物线方程为\(y=ax^2+bx(a<0,b>0)\),我们想要求出一组\(a,b\)使得它尽可能满足更多的要求.这个显然可以二分答案. 如何check当前的\(mid ...
- [bzoj2732][HNOI2012]射箭
Description 沫沫最近在玩一个二维的射箭游戏,如下图所示,这个游戏中的$x$轴在地面,第一象限中有一些竖直线段作为靶子,任意两个靶子都没有公共部分,也不会接触坐标轴.沫沫控制一个位于$(0, ...
- POJ3525 半平面交
题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似 ...
- 【kuangbin专题】计算几何_半平面交
1.poj3335 Rotating Scoreboard 传送:http://poj.org/problem?id=3335 题意:就是有个球场,球场的形状是个凸多边形,然后观众是坐在多边形的边上的 ...
- 【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交
4515: [Sdoi2016]游戏 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 304 Solved: 129[Submit][Status][ ...
- poj3335 半平面交
题意:给出一多边形.判断多边形是否存在一点,使得多边形边界上的所有点都能看见该点. sol:在纸上随手画画就可以找出规律:按逆时针顺序连接所有点.然后找出这些line的半平面交. 题中给出的点已经按顺 ...
- POJ 3130 How I Mathematician Wonder What You Are! /POJ 3335 Rotating Scoreboard 初涉半平面交
题意:逆时针给出N个点,求这个多边形是否有核. 思路:半平面交求多边形是否有核.模板题. 定义: 多边形核:多边形的核可以只是一个点,一条直线,但大多数情况下是一个区域(如果是一个区域则必为 ).核内 ...
随机推荐
- 【Log】logback指定配置文件(二)
通常我们在不同的环境使用不同的日志配置文件,本章讲指定logback的配置文件,如何使用logback参照[Log]logback的配置和使用(一) 写一个配置加载类,注意JoranConfigura ...
- 2018.06.30 BZOJ3083: 遥远的国度(换根树剖)
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 512 MB Description 描述 zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国 ...
- 2018.08.12 bzoj5301: [Cqoi2018]异或序列(前缀和+莫队)
传送门 简单的异或前缀和处理+莫队统计答案. 惊奇的发现无论开不开long long都能跑过... 代码: #include<bits/stdc++.h> #define N 100005 ...
- Linux 修改 IP地址 和 网关
修改IP地址和网关是很常见的操作,在做相关实验的时候,如果没有设置好,会带来很多不必要的麻烦.. 1. 修改IP地址vi /etc/sysconfig/network-scripts/ifcfg-et ...
- 对call() apply() 方法的简单理解
真的是非常简单的理解,我知道的并不多,在网上查找了很多的资料,还是只能了解一点皮毛,下面来整理出来,方便以后深入的去学习,也是对目前知道的知识点的巩固. 整理一些网上的经典解答: 1.一句话区分cal ...
- 20155327 2016-2017-4 《Java程序设计》第6周学习总结
20155327 2016-2017-4 <Java程序设计>第6周学习总结 教材学习内容总结 理解流与IO 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两 ...
- Node.js使用MySQL的连接池
使用Nodejs+MySQL肯定比PHP和MySQL的组合更适合做服务器端的开发. 使用Nodejs你会从他的异步行为中获益良多.比如,提升性能,你无须在从已有的MySQL数据库迁移到其他的NoSQL ...
- ios判断设备是iphone还是ipad
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...
- Eclipse的使用技巧
Eclipse有强大的编辑功能, 工欲善其事,必先利其器, 掌握Eclipse快捷键,可以大大提高工作效率. 小坦克我花了一整天时间, 精选了一些常用的快捷键操作,并且精心录制了动画, 让你一看就会. ...
- shell 脚本,将/etc/目录下所有的软链接文件输出
#!/bin/bash # cd /etc for a in *;do if [ -L $a ];then #如果文件存在,为软链接文件且指向的是文件,则返回真 echo $a fi done 测试: