BZOJ3963: [WF2011]MachineWorks
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3963
CDQ分治加凸包。具体看这篇题解:http://www.acmerblog.com/hdu-3842-machine-works-6844.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #define inf 1<<30 7 #define maxn 100005 8 #define ll long long 9 using namespace std; 10 int n,c,d,cases; 11 long long f[maxn]; 12 int read(){ 13 int x=0,f=1; char ch; 14 for(ch=getchar();ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1; 15 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; 16 return x*f; 17 } 18 struct fuck{int d,p,r,g; void init(){d=read();p=read();r=read();g=read();}}m[maxn]; 19 typedef pair<int,long long> pa; 20 pa a[maxn],b[maxn]; 21 long long h(int x){return f[x]-(ll)m[x].p+(ll)m[x].r-(ll)m[x].g*(ll)(m[x].d+1);} 22 bool cmp(fuck x,fuck y){return x.d<y.d;} 23 bool check(pa a,pa b,pa c){ 24 ll xa=b.first-a.first; ll xb=c.first-a.first; 25 ll ya=b.second-a.second; ll yb=c.second-a.second; 26 double tmp=(double)xa*yb-(double)ya*xb; 27 return tmp<0; 28 } 29 void solve(int l,int r){ 30 if(l==r) return; 31 int mid=(l+r)>>1; 32 solve(l,mid); 33 int na=0,nc=0; 34 for(int i=l;i<=mid;i++){ 35 if(f[i]>=m[i].p) a[++na]=pa(m[i].g,h(i)); 36 } 37 sort(a+1,a+na+1); 38 for(int i=1;i<=na;i++){ 39 while(nc>1&&!check(b[nc-1],b[nc],a[i])) nc--; 40 b[++nc]=a[i]; 41 } 42 int j=0; 43 for(int i=mid+1;i<=r;i++){ 44 ll a1,a2,b1,b2,x; 45 x=m[i].d; 46 while(j<nc){ 47 a1=b[j].first; a2=b[j+1].first; 48 b1=b[j].second; b2=b[j+1].second; 49 if(a1*x+b1>=a2*x+b2) break; 50 j++; 51 } 52 f[i]=max(f[i],(ll)b[j].first*x+b[j].second); 53 } 54 solve(mid+1,r); 55 } 56 int main(){ 57 for(n=read(),c=read(),d=read();n&&c&&d;n=read(),c=read(),d=read()){ 58 for(int i=1;i<=n;i++) m[i].init(); 59 sort(m+1,m+n+1,cmp); 60 m[++n].d=d+1; m[n].p=m[n].r=m[n].g=0; 61 for(int i=0;i<=n;i++) f[i]=c; 62 solve(0,n); 63 printf("Case %d: %lld\n",++cases,f[n]); 64 } 65 return 0; 66 }