#include #include using namespace std; typedef long long ll; typedef pair pll; #define MP make_pair #define X first #define Y second int n; int d; ll c; ll VERYBIG = 1LL << 62; const int MAXTEMP = 0; const int MAXN = 200000; struct machinetype { int day; ll r, p, g; bool operator < (const machinetype &o) const { return day < o.day; } }; machinetype machine[MAXN]; pll temp[MAXN]; int tempT; pll hull[MAXN]; int hullT; pll DP[MAXN]; void getQuo(ll dy, ll dx, ll &q, ll &r) { q = dy / dx; r = dy - dx * q; while(r < 0) { r += dx; q += 1LL; } while(r >= dx) { r -= dx; q -= 1LL; } //printf("%lld %lld %lld %lld\n", dy, dx, q, r); } int removeMid(pll a, pll b, pll c) { // (b.y - a.y) / (b.x - a.x) <= (c.y - b.y) / (c.x - b.x); ll dy1 = b.Y - a.Y; ll dx1 = b.X - a.X; ll q1, r1; getQuo(dy1, dx1, q1, r1); ll dy2 = c.Y - b.Y; ll dx2 = c.X - b.X; ll q2, r2; getQuo(dy2, dx2, q2, r2); if(q1 < q2) { return 1; } if(q1 > q2) { return 0; } if(r1 * dx2 <= r2 * dx1) { return 1; } else { return 0; } } void showHull() { printf("Hull:::"); for(int i = 0; i < hullT; ++i) { printf("(%lld, %lld) ", hull[i].X, hull[i].Y); } printf("\n"); } void moveToHull() { for(int i = 0; i < tempT; ++i) { hull[hullT++] = temp[i]; } tempT = 0; sort(hull, hull + hullT); //showHull(); int t = 0; for(int i = 0; i < hullT; ++i) { while(t > 0 && hull[t - 1].X == hull[i].X && hull[t - 1].Y <= hull[i].Y){ t --; } while(t > 1 && removeMid(hull[t - 2], hull[t - 1], hull[i])) { t--; } hull[t++] = hull[i]; } hullT = t; //showHull(); } void insert(pll p) { temp[tempT++] = p; } inline ll evalPnt(pll p, ll b) { return p.Y - b * p.X; } ll queryHull(ll b) { if(hullT == 0) { return -VERYBIG; } int p = 0; ll res = evalPnt(hull[0], b); if(hullT > 1) { res = max(res, evalPnt(hull[1], b)); } int del = 1<<18; while(del > 0) { if(p + del < hullT - 1) { ll v1 = evalPnt(hull[p + del], b); ll v2 = evalPnt(hull[p + del + 1], b); res = max(res, v1); res = max(res, v2); if(v2 > v1) { p += del; } } del /= 2; } return res; } ll query(ll b) { ll res = -VERYBIG; for(int i = 0; i < tempT; ++i) { res = max(res, temp[i].Y - temp[i].X * b); } res = max(res, queryHull(b)); return res; } int canBuy[MAXN]; int main() { int ct = 0; scanf("%d%lld%d", &n, &c, &d); while(n != 0 || c != 0 || d != 0) { for(int i = 0; i < n; ++i) { scanf("%d%lld%lld%lld", &machine[i].day, &machine[i].p, &machine[i].r, &machine[i].g); } sort(machine, machine + n); tempT = 0; hullT = 0; int i1 = 0; ll answer = c; memset(canBuy, 0, sizeof(canBuy)); for(int i = 0; i < n; ++i) { while(i1 < n && machine[i1].day < machine[i].day) { if(canBuy[i1]) { insert(DP[i1]); } i1++; } if(tempT >= MAXTEMP) { moveToHull(); } ll maxMoney = query(machine[i].day); maxMoney = max(maxMoney, c); //printf("%d %lld\n", machine[i].day, maxMoney); if(maxMoney >= machine[i].p) { canBuy[i] = 1; ll newMoney = maxMoney - machine[i].p + machine[i].r; ll x = -machine[i].g; ll y = newMoney + x * ll(machine[i].day + 1); DP[i] = make_pair(x, y); //printf(":::%lld %lld\n", x, y); answer = max(answer, y - x * ll(d + 1)); } else { canBuy[i] = 0; } } ++ct; printf("Case %d: %lld\n", ct, answer); scanf("%d%lld%d", &n, &c, &d); } return 0; }