The first time to play dynamic convex package maintenance dp, feel learned a super many things.
First of all, set is so easy to use!!! Two queries can be implemented by controlling a flag, maintaining the convex hull and finding the slope K
But it's just overloaded operators and some of the details are disgusting, 90 lines to solve
There is a CDQ in the back, find time to learn, to see if you can deal with a large group of disgusting problems
GitHub's still not going to work, so find some time.
CODE:
1#include <cstdio>2#include <cstring>3#include <algorithm>4#include <iostream>5#include <Set>6#include <cmath>7 using namespacestd;8 Const Doubleesp=1e-7;9 Const intmaxn=101000;Ten intDCMP (Doublea) { One if(Fabs (a) <ESP)return 0; A returna<0?-1:1; - } - structnode{ the DoubleX,y,k;BOOLF; -NodeDouble_x,Double_y): X (_x), Y (_y), F (0){} -Node (): F (0){} -InlineBOOLError () {returnX>1e50;} +}error (1e51,0); -InlineBOOL operator== (ConstNode X,ConstNode Y) {returnDCMP (x.x-y.x) = =0;} +InlineBOOL operator< (ConstNode X,Constnode Y) { A if(x.f| | Y.F)returnDCMP (X.K-Y.K) >0; at Else returnDCMP (x.x-y.x) <0; - } -InlineDouble operator*(ConstNode X,ConstNode Y) {returnx.x*y.y-x.y*y.x;} -Inline nodeoperator-(ConstNode X,Constnode Y) { - node tmp; -tmp.x=x.x-y.x;tmp.y=x.y-y.y; in returntmp; - } toInlineDoubleCalc_k (node X,node y) {return(X.Y-Y.Y)/(x.x-y.x);} + Set<node>Gap; -typedefSet<node>:: iterator iter; the inline node lower (node x) { *ITER it=gap.lower_bound (x); $ returnIt==gap.end ()? error:*it;Panax Notoginseng } - inline node Next (node X) { theITER it=gap.upper_bound (x); + returnIt==gap.end ()? error:*it; A } the Inline node Pre (node X) { +ITER it=gap.lower_bound (x); - returnIt==gap.begin ()? error:* (--it); $ } $Inlinevoidins (Node A) { - if(Gap.empty ()) {a.k=0; Gap.insert (a);return;} -Node D1=pre (a), d2=Lower (a); the if(D1.error () &&d2.y>a.y)return ; - if((!d1.error ()) && (!d2.error ()) && (dcmp ((D2-D1) * (A-D1)) <=0))return ;Wuyi if(d2==a)return; theNode p1,p2=next (a); - for (;;) { WuP1=p2;p2=Next (p2); - if(P1.error () | | P2.error ()) Break; About if(DCMP ((p1-a) * (p2-a)) <=0) Break; $ Gap.erase (p1); - } -P2=pre (a); - for (;;) { AP1=p2;p2=Pre (P2); + if(P1.error () | | P2.error ()) Break; the if(DCMP ((p1-a) * (p2-a)) >=0) Break; - Gap.erase (p1); $ } theD1=pre (a), d2=next (a); the if(D1.error ()) a.k=0;Elsea.k=Calc_k (d1,a); Gap.insert (a); the if(!d2.error ()) Gap.erase (D2), d2.k=Calc_k (A,D2), Gap.insert (D2); the } -InlineDoubleGet_k (DoubleADoubleb) { inNode tmp;tmp.f=1; tmp.k=-a/b; thetmp=* (--Gap.lower_bound (TMP)); the returna*tmp.x+b*tmp.y; About } the DoubleA[MAXN],B[MAXN],R[MAXN],NA[MAXN],NB[MAXN],F[MAXN]; the intMain () { the intn,s; +scanf"%d%d",&n,&s); - for(intI=1; i<=n;i++) scanf ("%LF%LF%LF", a+i,b+i,r+i); thef[1]=s;Bayinb[1]=f[1]/(a[1]*r[1]+b[1]); theMax1]=nb[1]*r[1]; theINS (Node (na[1],nb[1])); - for(intI=2; i<=n;i++) { -F[i]=max (f[i-1],get_k (A[i],b[i])); thenb[i]=f[i]/(a[i]*r[i]+b[i]); thena[i]=nb[i]*R[i]; the Ins (node (na[i],nb[i)); the } -printf"%.3f\n", F[n]); the } the
[NOI2007] Currency exchange cash (dp+ dynamic convex bag)