1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| #include <bits/stdc++.h> #define MAXN 100005 #define int long long #define INF 1e15 #define eps 1e-10 using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+(ch^'0'); ch=getchar(); } return x*f; } struct Machine{ int d,p,r,g; }m[MAXN]; inline bool cmp(const Machine &A,const Machine &B){ return A.d<B.d; } int n,c,d; int ans[MAXN]; struct Point{ double x,y; int id; }p[MAXN],t[MAXN],q[MAXN]; inline bool cmp1(const Point &A,const Point &B){ return m[A.id].d<m[B.id].d; } inline bool cmp2(const Point &A,const Point &B){ if (A.x!=B.x) return A.x<B.x; else return A.y<B.y; } inline double operator * (const Point &A,const Point &B){ return A.x*B.y-A.y*B.x; } inline Point operator - (const Point &A,const Point &B){ return Point{A.x-B.x,A.y-B.y}; } inline Point operator + (const Point &A,const Point &B){ return Point{A.x+B.x,A.y+B.y}; } inline double Slope(const Point &A,const Point &B){ return (double)(A.y-B.y)/(double)(A.x-B.x); } inline void Msort1(int l,int r){ int mid=(l+r)>>1; int j=l,k=mid+1; for (register int i=l;i<=r;++i){ if (p[i].id<=mid) t[j++]=p[i]; else t[k++]=p[i]; } for (register int i=l;i<=r;++i) p[i]=t[i]; } inline void Msort2(int l,int r){ int mid=(l+r)>>1; int j=l,k=mid+1; for (register int i=l;i<=r;++i){ if (j<=mid&&(k>r||cmp2(p[j],p[k]))) t[i]=p[j++]; else t[i]=p[k++]; } for (register int i=l;i<=r;++i) p[i]=t[i]; } void CDQ(int l,int r){ if (l==r){ p[l].x=(double)m[l].g; p[l].y=(double)ans[l]+m[l].r-m[l].g*m[l].d-m[l].g; return ; } int mid=(l+r)>>1; Msort1(l,r); CDQ(l,mid); int head=1,rear=0; for (register int i=l;i<=mid;++i){ if (ans[p[i].id]<0) continue; while (head<rear&&(q[rear]-q[rear-1])*(p[i]-q[rear-1])>=0) rear--; q[++rear]=p[i]; } for (register int k=mid+1;k<=r;++k){ int i=p[k].id; while (head<rear&&(q[head+1]-q[head])*(Point{1,-m[i].d,1926})<=0) head++; int j=q[head].id; ans[i]=max(ans[i],ans[j]+m[j].r+m[j].g*(m[i].d-m[j].d-1)-m[i].p); } CDQ(mid+1,r); Msort2(l,r); } #undef int int main(){ #define int long long int Case=0; while (scanf("%lld%lld%lld",&n,&c,&d)!=EOF&&(n!=0&&c!=0&&d!=0)){ for (register int i=1;i<=n;++i){ m[i].d=read(),m[i].p=read(),m[i].r=read(),m[i].g=read(); p[i].id=i; } sort(m+1,m+1+n,cmp); sort(p+1,p+1+n,cmp1); for (register int i=1;i<=n;++i) ans[i]=-INF; ans[0]=c; CDQ(0,n); long long ret=c; for (register int i=1;i<=n;++i){ if (ans[i]>=0) ret=max(ret,(long long)(ans[i]+m[i].r+(d-m[i].d)*m[i].g)); } printf("Case %d: %lld\n",++Case,(long long)ret); } }
|