传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1492
推荐博客:http://www.cnblogs.com/zig-zag/archive/2013/04/24/3039418.html
保存cdq分治模版代码。
#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> const int maxn = 100005; const double eps = 1e-9, inf = 1e300; int n, s; double a[maxn], b[maxn], rate[maxn], f[maxn]; struct point { double x, y; int id; bool operator<(const point & rhs) const { if (fabs(x - rhs.x) < eps) { return y > rhs.y + eps; } return x + eps < rhs.x; } } stk[maxn], p[maxn], np[maxn]; struct query { double k; int id; } q[maxn], tq[maxn]; bool cmp(const query & aa, const query & ss) { return aa.k > ss.k; } inline double getk(const point & aa, const point & ss) { if (fabs(aa.x - ss.x) < eps) { return -inf; } return (ss.y - aa.y) / (ss.x - aa.x); } void slove(int left, int right) { if (left == right) { f[left] = std::max(f[left], f[left - 1]); p[left].y = f[left] / (a[left] * rate[left] + b[left]); p[left].x = p[left].y * rate[left]; return; } int mid = (left + right) >> 1, idx1 = left, idx2 = mid + 1; for (int i = left; i <= right; ++i) { if (q[i].id <= mid) { tq[idx1++] = q[i]; } else { tq[idx2++] = q[i]; } } memcpy(q + left, tq + left, sizeof(query) * (right - left + 1)); slove(left, mid); int top = 0; stk[top++] = p[left]; for (int i = left + 1; i <= mid; ++i) { while (top > 1 && getk(p[i], stk[top - 1]) > getk(stk[top - 1], stk[top - 2]) + eps) { --top; } stk[top++] = p[i]; } int j = 0; for (int i = mid + 1; i <= right; ++i) { while (j < top - 1 && getk(stk[j], stk[j + 1]) > q[i].k + eps) { ++j; } f[q[i].id] = std::max(f[q[i].id], stk[j].x * a[q[i].id] + stk[j].y * b[q[i].id]); } slove(mid + 1, right); idx1 = left, idx2 = mid + 1; for (int i = left; i <= right; ++i) { if (idx1 <= mid && (p[idx1] < p[idx2] || idx2 > right)) { np[i] = p[idx1++]; } else { np[i] = p[idx2++]; } } memcpy(p + left, np + left, sizeof(point) * (right - left + 1)); } int main(void) { scanf("%d%d", &n, &s); f[0] = (double)s; for (int i = 1; i <= n; ++i) { scanf("%lf%lf%lf", a + i, b + i, rate + i); q[i] = (query){-a[i] / b[i], i}; } std::sort(q + 1, q + n + 1, cmp); slove(1, n); printf("%.3lf ", f[n]); return 0; }