标签:lazy a* stdout 题解 std set 最大 inf abs
显然按a/t从大到小排序,在同一块里时间可以任意
然后按a从小到大排序,只用考虑相邻的a段(证明丢到坐标系上,找最小的正斜率),化式子发现有x/T,把段里的可能时间取最大/最小即可直接算c
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define abs(x) ((x)>0?(x):-(x))
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define E 0.000000001
#define ll long long
#define file
using namespace std;
struct type{
double a,t,s;
int id;
} a[200001];
double L,R,Mid,sum,Sum,c,ans,mn[200001],mx[200001],Mn,Mx,Mn2,Mx2,A,s1,s2;
int n,i,j,k,l;
bool cmp(type x,type y) {return abs(x.s-y.s)>E && x.s>y.s || abs(x.s-y.s)<=E && x.t<y.t;}
bool Cmp(type x,type y) {return x.a<y.a;}
int main()
{
freopen("score.in","r",stdin);
#ifdef file
freopen("score.out","w",stdout);
#endif
scanf("%d",&n);
fo(i,1,n) scanf("%lf",&a[i].a);
fo(i,1,n) scanf("%lf",&a[i].t),a[i].s=a[i].a/a[i].t,sum+=a[i].t;
sort(a+1,a+n+1,cmp);
memset(mn,127,sizeof(mn));
memset(mx,254,sizeof(mx));
j=0;
fo(i,1,n)
{
j+=(i==1 || abs(a[i].s-a[i-1].s)>E);
a[i].id=j;
if (mn[j]>9223372036854775807ll) mn[j]=Sum;
Sum+=a[i].t;
mx[j]=max(mx[j],Sum/sum);
}
sort(a+1,a+n+1,Cmp);
c=1;
Mn=Mn2=-1;
fo(i,1,n)
{
if (Mn==-1) Mn=mn[a[i].id]+a[i].t,Mx=mx[a[i].id];
else Mn=min(Mn,mn[a[i].id]+a[i].t),Mx=max(Mx,mx[a[i].id]);
if (i==n || abs(a[i].a-a[i+1].a)>E)
{
if (Mn2>-1)
{
s1=a[i].a*Mx,s2=A*(Mn2/sum);
if (abs(s1-s2)>E && s1>s2)
c=min(c,(a[i].a-A)/(s1-s2));
}
Mn2=Mn,Mx2=Mx;
Mn=-1;A=a[i].a;
}
}
printf("%.11lf\n",c);
fclose(stdin);
fclose(stdout);
return 0;
}
标签:lazy a* stdout 题解 std set 最大 inf abs
原文地址:https://www.cnblogs.com/gmh77/p/13060947.html