首先分析一下题目
设抛物线为y=a*x^2+b*x
然后就是看是否存在a,b满足条件了
即y1<=xi*xi*a+xi*b<=y2
所以就是半平面交了
二分判断一下就……卡精度了QAQ
所以要用long double
不过判断半平面交是否为空集好像有期望O(n)的随机增量法,但是我不会啊
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define double long double
const int N=200000+10;
const double inf=1e15;
int read(){
char ch=getchar();int x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct point{
double x,y;
};
struct line{
point a,b;
double k;
int id;
}l[N];
point operator - (point a,point b){
return (point){a.x-b.x,a.y-b.y};
}
point operator + (point a,point b){
return (point){a.x+b.x,a.y+b.y};
}
point operator * (point a,double k){
return (point){a.x*k,a.y*k};
}
point operator / (point a,double k){
return (point){a.x/k,a.y/k};
}
double cross(point a,point b){
return a.x*b.y-a.y*b.x;
}
double cross(point a,point b,point c){
return cross(b-a,c-a);
}
bool cmp(line i,line j){
if(i.k==j.k)return cross(i.a,i.b,j.b)>0;
return i.k<j.k;
}
point getpoint(line l1,line l2){
double k1=cross(l1.a,l2.b,l1.b),k2=cross(l1.a,l1.b,l2.a),t=k2/(k1+k2);
return l2.a+((l2.b-l2.a)*t);
}
bool check(line l1,line l2,line l){
point p=getpoint(l1,l2);
return cross(l.a,p,l.b)>0;
}
int rk[N],dq[N],ln,bot,top;
bool HPI(int x){
int j=0;
for(int i=1;i<=ln;i++)
if(l[i].id<=x){
if(l[i].k!=l[rk[j]].k)j++;
rk[j]=i;
}
dq[bot=0]=rk[1];dq[top=1]=rk[2];
for(int i=3;i<=j;i++){
while(bot<top&&check(l[dq[top-1]],l[dq[top]],l[rk[i]]))top--;
while(bot<top&&check(l[dq[bot+1]],l[dq[bot]],l[rk[i]]))bot++;
dq[++top]=rk[i];
}
while(bot<top&&check(l[dq[top-1]],l[dq[top]],l[dq[bot]]))top--;
while(bot<top&&check(l[dq[bot+1]],l[dq[bot]],l[dq[top]]))bot++;
return top-bot>1;
}
point getpoint(double x,double y,double xi){
return (point){x,y/xi-xi*x};
}
int main(){
//freopen("a.in","r",stdin);
int n;scanf("%d",&n);
l[++ln].a=(point){-inf,-inf};l[ln].b=(point){inf,-inf};
l[++ln].a=(point){inf,-inf};l[ln].b=(point){inf,inf};
l[++ln].a=(point){inf,inf};l[ln].b=(point){-inf,inf};
l[++ln].a=(point){-inf,inf};l[ln].b=(point){-inf,-inf};
for(int i=1;i<=n;i++){
double x,y1,y2;
x=read();y1=read();y2=read();
l[++ln].a=getpoint(1,y2,x);
l[ln].b=getpoint(-1,y2,x);
l[++ln].a=getpoint(-1,y1,x);
l[ln].b=getpoint(1,y1,x);
l[ln].id=l[ln-1].id=i;
}
for(int i=1;i<=ln;i++)l[i].k=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);
sort(l+1,l+1+ln,cmp);
int L=1,R=n;
while(L<=R){
int mid=L+R>>1;
if(HPI(mid))L=mid+1;
else R=mid-1;
}
printf("%d\n",L-1);
return 0;
}