题目:
题解:
这个关卡包含前面的特性很明显是二分
判断的话随便画画柿子就有
y1<=ax2+bx<=y2
,而
x,y1,y2
都是已知的,这不就是一个关于a,b的直线了吗,半平面交?
这个数据范围也只有nlogn的半平面交能过了吧,总复杂度
O(nlog2n)
选择直线上的点的时候,注意不能选择与坐标轴的交点,因为这样过原点的直线并没有办法表示,那就随便选一个呗= =
因为这里的直线不一定能交出啥来,我们必须在外面加一个巨大的框,注意这里加的是a,b的框,a是一定小于0的,要求b大于0,对称轴在右。
还有就是判断在线右边的时候一定要加上‘=’,选eps和INF都要好好考虑,INF不能选的太大,eps不能太大也不能太小= =,double也换掉。
在结构体里重载运算符是非常快的。
代码:
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const long double INF=1e11;//
const int N=200050;
const long double eps=1e-12;//
const long double X1=3.0;
const long double X2=-1.0;
int dcmp(long double x)
{
if (x>=-eps && x<=eps) return 0;
return (x>0)?1:-1;
};
struct po
{
long double x,y;
po (long double X=0,long double Y=0){x=X;y=Y;}
}p[N],d[N];
struct line
{
po x,v;long double ang;
line (po X=po(0,0),po V=po(0,0)){x=X; v=V; ang=atan2(v.y,v.x);}
bool operator <(line a)const {return ang<a.ang;}
}L[N],q[N],s[N];int head,tail;
po operator -(po x,po y){return po(x.x-y.x,x.y-y.y);}
po operator +(po x,po y){return po(x.x+y.x,x.y+y.y);}
po operator *(po x,long double y){return po(x.x*y,x.y*y);}
long double cj(po x,po y){return x.x*y.y-x.y*y.x;}
po jd(line a,line b)
{
po u=a.x-b.x;
long double t=cj(b.v,u)/cj(a.v,b.v);
return a.x+a.v*t;
}
bool Onleft(line x,po y){return dcmp(cj(x.v,y-x.x))>=0;} //
bool halfp(int n)
{
for (int i=1;i<=n;i++) L[i]=s[i];
sort(L+1,L+n+1);
head=tail=1; q[1]=L[1];
for (int i=2;i<=n;i++)
{
while (head<tail && !Onleft(L[i],p[tail-1])) tail--;
while (head<tail && !Onleft(L[i],p[head])) head++;
q[++tail]=L[i];
if (dcmp(cj(q[tail].v,q[tail-1].v))==0)
{
tail--;
if (Onleft(q[tail],L[i].x)) q[tail]=L[i];
}
if (head<tail) p[tail-1]=jd(q[tail],q[tail-1]);
}
while (head<tail && !Onleft(q[head],p[tail-1])) tail--;
if (tail-head<=1) return 0;return 1;//
}
int read()
{
char c=getchar();int x=0,f=1;
while (c<'0' || c>'9'){if (c=='-') f=-1;c=getchar();}
while (c>='0' && c<='9') x=x*10+c-'0',c=getchar();
return f*x;
}
int main()
{
long double x,y1,y2;int n,id=0;
n=read();
s[++id]=line(po(0,0),po(0,INF));
s[++id]=line(po(0,INF),po(-INF,0));
s[++id]=line(po(-INF,INF),po(0,-INF));
s[++id]=line(po(-INF,0),po(INF,0));
for (int i=1;i<=n;i++)
{
x=read(); y1=read(); y2=read();
po a=po(X1,(y1-x*x*X1)/x);
po b=po(X2,(y1-x*x*X2)/x);
s[++id]=line(b,a-b);
a=po(X1,(y2-x*x*X1)/x);
b=po(X2,(y2-x*x*X2)/x);
s[++id]=line(a,b-a);
}
int l=1,r=n,ans;
while (l<=r)
{
int mid=(l+r)>>1;
if (halfp(mid*2+4)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d",ans);
}