首先分析一下题目
设抛物线为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; }