# [WF 2011]MachineWorks

## Description

$1\leq n\leq 10^5$

## Solution

$$f_i=\max{f_j+(d_i-d_j-1)g_j+r_j}-p_i$$

## Code

#include <bits/stdc++.h>
using namespace std;
#define ll __int128
#define x(i) (1ll*a[i].g)
#define y(i) (1ll*(a[i].d+1)*a[i].g-a[i].r-f[i])
const int N = 1e5+5;

int n, c, d, ed[N], q[N], head, tail;
ll f[N];
struct tt {
int d, p, r, g;
bool operator < (const tt &b) const {
return d < b.d;
}
} a[N];

void cdq(int l, int r) {
if (l == r) {
if ((c >= a[l].p ? c-a[l].p : -1) > f[l])
f[l] = (c >= a[l].p ? c-a[l].p : -1);
ed[l] = l; return;
}
int mid = (l+r)>>1;
cdq(l, mid);
head = 0, tail = -1; int flag = 0;
for (int i = l; i <= mid; i++) {
if (i != l && x(ed[i]) != x(ed[i-1])) flag = 0;
if (f[ed[i]] < 0 || flag) continue;
while (head < tail && 1ll*(y(ed[i])-y(q[tail]))*(x(ed[i])-x(q[tail-1])) <= 1ll*(y(ed[i])-y(q[tail-1]))*(x(ed[i])-x(q[tail]))) --tail;
q[++tail] = ed[i]; flag = 1;
}
for (int i = mid+1; head <= tail && i <= r; i++) {
int j = q[head]; if (f[j] < 0) puts("?");
if (f[j]+1ll*(a[i].d-a[j].d-1)*a[j].g+a[j].r >= a[i].p)
f[i] = max(f[i], f[j]+1ll*(a[i].d-a[j].d-1)*a[j].g+a[j].r-a[i].p);
}
cdq(mid+1, r);
int i = l, j = mid+1, p = l-1;
while (i <= mid && j <= r)
if (x(ed[i]) < x(ed[j]) || (x(ed[i]) == x(ed[j]) && y(ed[i]) < y(ed[j]))) q[++p] = ed[i++];
else q[++p] = ed[j++];
while (i <= mid) q[++p] = ed[i++];
while (j <= r) q[++p] = ed[j++];
for (int i = l; i <= r; i++) ed[i] = q[i];
}
int main() {
int t = 0;
while (true) {
scanf("%d%d%d", &n, &c, &d);
if (!(n|c|d)) break;
for (int i = 1; i <= n; i++)
scanf("%d%d%d%d", &a[i].d, &a[i].p, &a[i].r, &a[i].g);
sort(a+1, a+n+1);
for (int i = 1; i <= n; i++) f[i] = -1;
cdq(1, n);
ll ans = c;
for (int i = 1; i <= n; i++)
if (f[i] >= 0) ans = max(ans, f[i]+1ll*(d-a[i].d)*a[i].g+a[i].r);
printf("Case %d: %lld\n", ++t, ans);
}
return 0;
}
posted @ 2020-08-09 01:25  NaVi_Awson  阅读(137)  评论(0编辑  收藏  举报