BZOJ1492:[NOI2007]货币兑换Cash 斜率优化+cdq分治
思路:
我才发现自己以前写的模板多么傻逼.现在的模板总算是科学了.
不得不说cdq分治还是过于强大了OTZ.
另外等号问题只有在对拍的时候才能改过来了?实在不懂为什么要加一个等号.
(另外实数的手写读入丧心病狂)
#include<cmath> #include<cctype> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef double f2; namespace Fio{ inline int getc(){ static const int L=1<<15;static char buf[L],*S=buf,*T=buf; if(S==T){T=(S=buf)+fread(buf,1,L,stdin);if(S==T)return EOF;} return*S++; } template<typename T>inline void Getint(T&x){ int c;while(!isdigit(c=getc())&&c!='-');bool sign=c=='-'; x=sign?0:c-'0';while(isdigit(c=getc()))x=(x<<1)+(x<<3)+c-'0'; if(sign)x=-x; } template<typename T>inline void Getfloat(T&x){ int c;while(!isdigit(c=getc())&&c!='-');bool sign=c=='-'; x=sign?0:c-'0';while(isdigit(c=getc()))x=10*x+c-'0'; if(c=='.'){double f=0.1;while(isdigit(c=getc()))x+=f*(c-'0'),f/=10;} if(sign)x=-x; if(fabs(x)<1e-8)x=0; } } #define N 100010 f2 f[N],A[N],B[N],na[N],nb[N],Rat[N]; int seq[N],ins[N]; bool cmp(const int&a,const int&b){return -A[a]*B[b]>-A[b]*B[a];} int q[N],qq[N],stk[N],top; inline void Solve(int l,int r){ if(l==r){ f[q[l]]=max(f[q[l]],f[q[l]-1]); nb[q[l]]=f[q[l]]/(A[q[l]]*Rat[q[l]]+B[q[l]]),na[q[l]]=nb[q[l]]*Rat[q[l]]; return; } int mid=(l+r)>>1; register int i,j,k; int p1=l,p2=mid+1;for(i=l;i<=r;++i)if(q[i]<=mid)qq[p1++]=q[i];else qq[p2++]=q[i]; memcpy(q+l,qq+l,(r-l+1)*sizeof(int)); Solve(l,mid); for(top=0,i=l;i<=mid;++i){ while(top>1&&(nb[q[i]]-nb[stk[top]])*(na[stk[top]]-na[stk[top-1]])>=(nb[stk[top]]-nb[stk[top-1]])*(na[q[i]]-na[stk[top]]))--top; stk[++top]=q[i]; } j=mid+1; for(i=1;i<=top;++i) while(j<=r&&(i==top||((-A[q[j]]/B[q[j]])*(na[stk[i+1]]-na[stk[i]])>=nb[stk[i+1]]-nb[stk[i]])))f[q[j]]=max(f[q[j]],A[q[j]]*na[stk[i]]+B[q[j]]*nb[stk[i]]),++j; Solve(mid+1,r); for(i=k=l,j=mid+1;i<=mid&&j<=r;)qq[k++]=na[q[i]]<na[q[j]]?q[i++]:q[j++]; while(i<=mid)qq[k++]=q[i++]; while(j<=r)qq[k++]=q[j++]; memcpy(q+l,qq+l,(r-l+1)*sizeof(int)); } int main(){ int n;Fio::Getint(n),Fio::Getfloat(f[1]); register int i,j;for(i=1;i<=n;++i)Fio::Getfloat(A[i]),Fio::Getfloat(B[i]),Fio::Getfloat(Rat[i]); /*int n;scanf("%d%lf",&n,&f[1]); register int i,j;for(i=1;i<=n;++i)scanf("%lf%lf%lf",&A[i],&B[i],&Rat[i]);*/ for(i=1;i<=n;++i)q[i]=i;sort(q+1,q+n+1,cmp); Solve(1,n); printf("%.3lf",f[n]); return 0; }