# [HNOI2012]射箭

## Solution

### Part1：限制条件与转化

$lowy_i\leq Ax_i^2+Bx_i+C\leq highy_i$

$\frac{lowy_i}{x_i}\leq Ax_i+B+C\leq \frac{highy_i}{x_i}$

$Ax_i+B+C-\frac{lowy_i}{x_i}\geq 0$

$Ax_i+B+C-\frac{highy_i}{x_i}\leq 0$

n条直线就转化成了$$2*n$$个不等式的约束

### Part2: 求解

$Ax_i+B-\frac{lowy_i}{x_i}\geq 0$

$Ax_i+B-\frac{highy_i}{x_i}\leq 0$

（为了保证半平面交是封闭图形，INF处也要加上约束）

## Code

#include<bits/stdc++.h>
using namespace std;
#define re register
#define int long long
#define get getchar()
#define in inline
#define db double
{
int t=0, x=1; char ch=get;
while(ch!='-' && (ch<'0' || ch>'9')) ch=get;
if(ch=='-') ch=get, x=-1;
while(ch<='9' && ch>='0') t=t*10+ch-'0', ch=get;
return t*x;
}
const int _=4e5+23;
const int inf=2e15;
const db eps=1e-15;
struct vec{
db x,y;
vec(){x=y=0;}
vec(db a,db b){x=a, y=b;}
vec operator +(const vec b)const {return vec(x+b.x, y+b.y);}
vec operator -(const vec b)const {return vec(x-b.x, y-b.y);}
vec operator ^(const db b)const {return vec(x*b,y*b);}
db operator &(const vec b)const {return x*b.x+y*b.y;}
db operator *(const vec b)const {return x*b.y-y*b.x;}
db dis(){ return sqrt(x*x+y*y);}
}a[_];
struct line{
vec st, ed;int id;vec c;
bool operator <(const line l)const {
db A=atan2(c.y,c.x), B=atan2(l.c.y,l.c.x);
if(fabs(A-B)>eps) return A<B;
return c*(l.ed-st)+eps<0;
}
}l[_], qwe[_], q[_];
vec intersection(line l1,line l2)
{
vec st1=l1.st, st2=l2.st;
vec a=l1.c, b=l2.c, c=st2-st1;
if(fabs(b*a)<eps) return vec(-1e12,-1e12);
return st1+(a^((b*c)/(b*a)));
}
int n, m, hd, tl;
bool check(line a,line b,line c)
{
vec p=intersection(b,c);
return (a.c*(p-a.st))+eps<0;
}
in int solve(int cnt,int lim)
{
int tot=0; tl=0, hd=1;
for(re int i=1;i<=cnt;++i)
{
if(l[i].id>lim) continue;
if(i>1 && fabs(atan2(l[i].c.y,l[i].c.x)-atan2(l[i-1].c.y, l[i-1].c.x))<eps)
continue;
qwe[++tot]=l[i];
}
m=tot;
for(re int i=1;i<=m;++i)
{
while(tl>hd && check(qwe[i], q[tl], q[tl-1])) tl--;
while(tl>hd && check(qwe[i], q[hd], q[hd+1])) hd++;
q[++tl]=qwe[i];
}
while(tl>hd && check(q[hd], q[tl], q[tl-1])) tl--;
while(tl>hd && check(q[tl], q[hd], q[hd+1])) hd++;
return tl-hd+1>=3;
}
db X[_], hy[_], ly[_];
in int check(int tot,int lim) {    return solve(tot,lim); }
signed main()
{
int tot=0;
l[++tot]=(line){vec(-inf,eps),vec(-eps,eps),0};
l[++tot]=(line){vec(-eps,eps),vec(-eps,inf),0};
l[++tot]=(line){vec(-eps,inf),vec(-inf,inf),0};
l[++tot]=(line){vec(-inf,inf),vec(-inf,eps),0};
for(re int i=1;i<=n;++i)
{
l[++tot]=(line){vec(0,ly[i]/X[i]),vec(1,ly[i]/X[i]-X[i]),i};
l[++tot]=(line){vec(1,hy[i]/X[i]-X[i]),vec(0,hy[i]/X[i]),i};
}
for(re int i=1;i<=tot;++i) l[i].c=l[i].ed-l[i].st;
sort(l+1,l+tot+1);
int l=1, r=n,ans=0;
while(l<=r)
{
int mid=l+r>>1;
if(check(tot,mid)) l=mid+1,ans=mid;
else r=mid-1;
}
cout<<ans<<endl;
return 0;
}


posted @ 2022-01-03 20:22  yzhx  阅读(65)  评论(1编辑  收藏  举报