传送门:[Submit]
本来写了一个详细的题解。。。。。。。。
但是TM博客园不保存。。。。。。
于是我就直接复制论文了吧。。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<cstring> 6 #include<cmath> 7 #define eps 1e-9 8 #define inf 0x7fffffff 9 #define ll long long 10 #define N 100005 11 using namespace std; 12 struct data{double a,b,rate,k,x,y; int id; 13 }q[N],t[N]; 14 double f[N]; 15 int s[N]; 16 int n; 17 bool cmp(data a, data b){ return a.k>b.k; 18 } 19 double getk(int a,int b) 20 { 21 if(!b)return -1e20; 22 if(fabs(q[a].x-q[b].x)<eps)return 1e20; 23 return (q[b].y-q[a].y)/(q[b].x-q[a].x); 24 } 25 void solve(int l,int r) 26 { 27 if (l==r) 28 { 29 f[l]=max(f[l],f[l-1]); 30 q[l].y=f[l]/(q[l].b+q[l].rate*q[l].a); 31 q[l].x=q[l].rate*q[l].y; 32 return; 33 } 34 int mid=(l+r)>>1,l1=l,l2=mid+1; 35 for (int i=l; i<=r; i++) 36 if (q[i].id<=mid) t[l1++]=q[i]; else t[l2++]=q[i]; 37 for (int i=l; i<=r; i++) q[i]=t[i]; 38 solve(l,mid); 39 int top=0; 40 for (int i=l; i<=mid; i++) 41 { 42 while (top>1 && getk(s[top-1],s[top]) < getk(s[top-1],i)+eps)top--; 43 s[++top]=i; 44 } 45 s[++top]=0; 46 int j=1; 47 for (int i=mid+1; i<=r; i++) 48 { 49 while (j<top && getk(s[j],s[j+1])+eps > q[i].k) j++; 50 f[q[i].id]=max(f[q[i].id],q[s[j]].x*q[i].a+q[s[j]].y*q[i].b); 51 } 52 solve(mid+1,r); 53 l1=l;l2=mid+1; 54 for (int i=l; i<=r; i++) 55 if ((q[l1].x<q[l2].x || l2>r) && l1<=mid) t[i]=q[l1++]; else t[i]=q[l2++]; 56 for (int i=l; i<=r; i++) q[i]=t[i]; 57 } 58 int main() 59 { 60 scanf("%d%lf",&n,&f[0]); 61 for (int i=1; i<=n; i++) 62 { 63 scanf("%lf%lf%lf",&q[i].a,&q[i].b,&q[i].rate); 64 q[i].k=-q[i].a/q[i].b; q[i].id=i; 65 } 66 sort(q+1,q+1+n,cmp); 67 solve(1,n); 68 printf("%0.3lf",f[n]); 69 }
日常一膜:CYS,CYY,LS,YZW,YWF,OYZX..............