传送门:bzoj1492
题解
斜率优化+cdq分治
代码
#include<bits/stdc++.h>
using namespace std;
typedef double db;
const int N=1e5+10;
const db eps=1e-10,inf=2e9;
int n,stk[N],top;db f[N];
struct Q{
db a,b,rt,k;int id;
inline void ini(){
scanf("%lf%lf%lf",&a,&b,&rt);
k=-a/b;
}
bool operator <(const Q&ky)const{
return k<ky.k;
}
}t[N],res[N];
struct P{
db x,y;
P(db x_=0,db y_=0):x(x_),y(y_){};
bool operator <(const P&ky)const{
return (x<ky.x+eps || (fabs(x-ky.x)<eps && y<ky.y+eps));
}
P operator -(const P&ky)const{return P(x-ky.x,y-ky.y);}
db operator ^(const P&ky)const{return x*ky.y-y*ky.x;}
}p[N],rep[N];
inline bool onl(P A,P B,P C){return ((B-A)^(C-B))+eps>0;}
inline db slp(P A,P B)
{
if(fabs(A.x-B.x)<=eps) return inf;
return (B.y-A.y)/(B.x-A.x);
}
void solve(int l,int r)
{
if(l==r){
f[l]=max(f[l],f[l-1]);
p[l].y=f[l]/(t[l].a*t[l].rt+t[l].b);
p[l].x=p[l].y*t[l].rt;
return;
}
int k,mid=(l+r)>>1,i=l,j=mid+1;
for(k=l;k<=r;++k){
if(t[k].id<=mid) res[i++]=t[k];
else res[j++]=t[k];
}
for(k=l;k<=r;++k) t[k]=res[k];
solve(l,mid);
top=0;
for(k=l;k<=mid;++k){
for(;top>1 && onl(p[stk[top-1]],p[stk[top]],p[k]);--top);
stk[++top]=k;
}
for(i=1,k=r;k>mid;--k){
for(;i<top && slp(p[stk[i]],p[stk[i+1]])+eps>t[k].k;++i);
f[t[k].id]=max(f[t[k].id],t[k].a*p[stk[i]].x+t[k].b*p[stk[i]].y);
}
solve(mid+1,r);
i=l;j=mid+1;
for(k=l;k<=r;++k){
if((j>r)||(i<=mid && p[i]<p[j])) rep[k]=p[i++];
else rep[k]=p[j++];
}
for(k=l;k<=r;++k) p[k]=rep[k];
}
int main(){
int i;
scanf("%d%lf",&n,&f[0]);
for(i=1;i<=n;++i) t[i].ini(),t[i].id=i;
sort(t+1,t+n+1);
solve(1,n);
printf("%.3lf",f[n]);
return 0;
}