BZOJ3963: [WF2011]MachineWorks

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3963

CDQ分治加凸包。具体看这篇题解:http://www.acmerblog.com/hdu-3842-machine-works-6844.html

 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 }
View Code

 

posted @ 2016-05-26 10:26  I'mLS  阅读(168)  评论(0编辑  收藏  举报