题目讲解:http://blog.csdn.net/thy_asdf/article/details/46686351
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<bitset>
#include<stack>
#include<set>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define inf 1e11
#define eps 1e-9
#define pii pair<int,int>
#define MP make_pair
#define LL long long
#define ULL unsigned long long
#define N ( 300000 + 10 )
#define M ( 200000 + 10)
#define mod 1000000007
double dp[N], a[N], b[N], r[N], x[N], y[N];
int ch[N][2];
double lk[N], rk[N];
int par[N];
int root, sz;
int n;
void rot(int x) {
int y = par[x], d = ch[y][1] == x;
ch[y][d] = ch[x][!d];
if(ch[x][!d]) par[ch[x][!d]] = y;
ch[x][!d] = y;
par[x] = par[y];
par[y] = x;
if(par[x]) ch[par[x]][ch[par[x]][1] == y] = x;
}
void splay(int x, int goal) {
while(par[x] != goal) {
int f = par[x], ff = par[f];
if(ff == goal)
rot(x);
else if((ch[ff][1] == f) == (ch[f][1] == x))
rot(f), rot(x);
else rot(x), rot(x);
}
if(!goal) root = x;
}
int find(double x) {
if(!root) return 0;
int u = root;
while(u) {
if(lk[u] < x) u = ch[u][0];
else if(rk[u] > x) u = ch[u][1];
else if(lk[u] >= x && x >= rk[u]) return u;
}
return u;
}
void insert(int i) {
if(root == 0) {
root = ++sz;
lk[sz] = inf;
rk[sz] = -inf;
return ;
}
int u = root;
while(u) {
if(x[i] <= x[u]) {
if(!ch[u][0]) {
ch[u][0] = ++sz, par[sz] = u, splay(sz, 0);
return ;
}
else u = ch[u][0];
}
else {
if(!ch[u][1]) {
ch[u][1] = ++sz, par[sz] = u, splay(sz, 0);
return ;
}
else u = ch[u][1];
}
}
}
double get(int i, int j) {
if(fabs(x[i] - x[j]) < eps) return -inf;
return (y[i] - y[j]) / (x[i] - x[j]);
}
int getl(int x) {
int t = ch[x][0];
int ans = t;
while(t) {
if(lk[t] >= get(t, x)) ans = t, t = ch[t][1];
else t = ch[t][0];
}
return ans;
}
int getr(int x) {
int t = ch[x][1], ans = t;
while(t) {
if(rk[t] <= get(t, x)) ans = t, t = ch[t][0];
else t = ch[t][1];
}
return ans;
}
void maintain(int x) {
splay(x, 0);
if(ch[x][0]) {
int ls = getl(x);
splay(ls, root);
par[ch[ls][1]] = 0, ch[ls][1] = 0;
rk[ls] = lk[x] = get(x, ls);
}
else lk[x] = inf;
if(ch[x][1]) {
int rs = getr(x);
splay(rs, root);
par[ch[rs][0]] = 0, ch[rs][0] = 0;
lk[rs] = rk[x] = get(x, rs);
}
else rk[x] = -inf;
if(lk[x] <= rk[x]) {
splay(x, 0);
int ls = ch[x][0], rs = ch[x][1];
if(!ls && !rs) {
root = 0;
return;
}
if(!ls) {
root = rs;
par[rs] = 0;
lk[rs] = inf;
return ;
}
if(!rs) {
root = ls;
par[ls] = 0;
rk[ls] = -inf;
return ;
}
par[ch[x][0]] = 0, ch[x][0] = 0;
splay(ls, 0);
ch[ls][1] = ch[x][1], par[ch[x][1]] = ls;
rk[ls] = lk[rs] = get(ls, rs);
}
}
int main() {
freopen("in.in", "r", stdin);
scanf("%d", &n);
scanf("%lf", &dp[0]);
for(int i = 1; i <= n; ++i) {
scanf("%lf%lf%lf\n", &a[i], &b[i], &r[i]);
}
for(int i = 1; i <= n; ++i) {
int j = find(-a[i]/b[i]);
dp[i] = max(dp[i-1], x[j] * a[i] + y[j] * b[i]);
y[i] = dp[i] / (a[i] * r[i] + b[i]);
x[i] = y[i] * r[i];
insert(i);
maintain(i);
}
printf("%.3lf\n", dp[n]);
}