Solution
推一下发现这个斜率优化不满足任何性质,那么平衡树维护凸包
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define reg register
#define For(i,a,b) for(reg int i=a;i<=b;++i)
#define Down(i,a,b) for(reg int i=a;i<=b;++i)
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
const double inf=1e18+10,eps=1e-9;
const int N=1e5+10;
int n,st,rt;
int ls[N],rs[N],fa[N];
double a[N],b[N],rat[N],l[N],r[N],x[N],y[N],f[N];
inline void rotate(int x)
{
int y=fa[x],z=fa[y];
if(ls[z]==y) ls[z]=x; else rs[z]=x;
if(ls[y]==x) ls[y]=rs[x],fa[rs[x]]=y,rs[x]=y;
else rs[y]=ls[x],fa[ls[x]]=y,ls[x]=y;
fa[y]=x; fa[x]=z;
return ;
}
inline void splay(int x,int g)
{
while(fa[x]!=g)
{
int y=fa[x],z=fa[y];
if(z!=g) rotate((ls[z]==y)^(ls[y]==x)?x:y);
rotate(x);
} if(!g) rt=x;
return ;
}
inline int find(int x,double num)
{
if(!x) return 0;
if(l[x]+eps>=num&&r[x]<=num+eps) return x;
if(l[x]<num+eps) return find(ls[x],num);
return find(rs[x],num);
}
inline double calc(int p,int q)
{
if(fabs(x[p]-x[q])<eps) return -inf;
return (y[p]-y[q])/(x[p]-x[q]);
}
inline int pre(int x)
{
int now=ls[x],res=now;
while(now)
{
if(l[now]+eps>=calc(now,x)) res=now,now=rs[now];
else now=ls[now];
} return res;
}
inline int nxt(int x)
{
int now=rs[x],res=now;
while(now)
{
if(r[now]<=eps+calc(now,x)) res=now,now=ls[now];
else now=rs[now];
} return res;
}
inline void del(int x)
{
rt=ls[x]; fa[rt]=0; fa[rs[x]]=rt; rs[rt]=rs[x];
r[rt]=l[rs[x]]=calc(rt,rs[x]);
return ;
}
inline void work(int x)
{
splay(x,0);
if(ls[x])
{
int p=pre(x); splay(p,x); rs[p]=0;
r[ls[x]]=l[x]=calc(ls[x],x);
}else l[x]=inf;
if(rs[x])
{
int tmp=nxt(x); splay(tmp,x); ls[tmp]=0;
l[rs[x]]=r[x]=calc(rs[x],x);
}else r[x]=-inf;
if(l[x]<=eps+r[x]) del(x);
return ;
}
inline void insert(int &now,int fat,int id)
{
if(!now){now=id; fa[now]=fat; return ;}
if(x[id]<=x[now]+eps) insert(ls[now],now,id); else insert(rs[now],now,id);
return ;
}
signed main()
{
n=read(); scanf("%lf",&f[0]);
For(i,1,n)
{
scanf("%lf%lf%lf",&a[i],&b[i],&rat[i]);
int pos=find(rt,-1.0*a[i]/b[i]);
f[i]=max(f[i-1],x[pos]*a[i]+y[pos]*b[i]);
y[i]=f[i]*1.0/(rat[i]*a[i]+b[i]); x[i]=rat[i]*y[i];
insert(rt,0,i); work(i);
}
printf("%.6lf
",f[n]);
return 0;
}
}
signed main(){return yspm::main();}