BZOJ4570: [Scoi2016]妖怪
答案打出来发现是关于a/b的单峰函数,直接三分,复杂度$O(nlogw)$。
然后T了……卡常数……
显然最大值在右上凸壳上,于是先跑个凸包。
然后上凸壳上的点数<=4……
然后就过了这什么破题什么破数据……
#include<bits/stdc++.h> using namespace std; typedef double flo; typedef long long ll; const int N=1e6; struct buf{ char z[3<<23],*s; buf():s(z){z[fread(z,1,sizeof z,stdin)]=0;} operator int(){ int x=0; while(*s<48)++s; while(*s>47) x=x*10+*s++-48; return x; } }it; struct vec{int x,y;}; vec c[N],r[N]; ll det(vec a,vec b){ return(ll)a.x*b.y-(ll)a.y*b.x; } vec operator-(vec a,vec b){ vec c={a.x-b.x,a.y-b.y}; return c; } bool operator<(vec a,vec b){ return a.x<b.x||a.x==b.x&&a.y<b.y; } int n,m; flo cal(flo k){ flo s=-1e18; for(int i=0;i<m;++i) s=max(s,r[i].x*(k+1)+r[i].y*(1/k+1)); return s; } int main(){ n=it; for(int i=0;i<n;++i) c[i].x=it,c[i].y=it; sort(c,c+n); for(int i=n-1;~i;--i){ while(m>1&&det(c[i]-r[m-1],c[i]-r[m-2])>=0)--m; r[m++]=c[i]; } flo s1=1e-4,s2=1e4; while(s2-s1>1e-12){ flo s3=s1+(s2-s1)/3; flo s4=s2-(s2-s1)/3; cal(s3)<cal(s4)?s2=s4:s1=s3; } printf("%.4f\n",cal(s1)); }