Similar to the slope of the optimization of things, really CF e will be the test center algorithm AH.
It feels like this optimization should be very common, but the line is only the first quadrant, but the insertion, and the find operation is unchanged, by the angle of the order can be directly used in this template.
#include <iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespaceStd;typedefLong Longll;structline{ll A, B; llGet(ll x) {returna*x+b; }};structconvex_hull{intsize; Line ls[200200]; voidinit () {size=0; } BOOLIs_bad (intOneintBoth,intTHREE)//currently convex package set is xxx12 to insert 3, determine whether to delete 2{line L1=ls[one],l2=ls[two],l3=Ls[three]; return(l2.b-l1.b) * (l1.a-l3.a) >= (l3.b-l1.b) * (l1.a-l2.a);//I'm sure I can do that! } voidAdd_line (ll a,ll b) {ls[size+ +] = line{a,b};//is it possible to write like this? while(size>=3&& Is_bad (size-3, size-2, size-1) ) {ls[size-2] = ls[size-1]; size--; }} ll query (ll x) {intb=-1, d=size-1; while(D-b >1) { intMid= (b+d)/2; if(Ls[mid].Get(x) <= ls[mid+1].Get(x)) {b=mid; } ElseD =mid; } returnLS[D].Get(x); }};#defineN 200200ll Sum[n];ll Ans,tans; Convex_hull CV;intG[n];intMain () {intN; CIN>>N; sum[0]=0; for(intI=1; i<=n;i++) {scanf ("%d", g+i); Sum[i]= sum[i-1]+G[i]; Ans+ = (LL) i*G[i]; } cv.init (); for(intI=2; i<=n;i++) {Cv.add_line (i-1,-sum[i-2]); Tans= Max (Tans,cv.query (G[i]) +sum[i-1]-(LL) i*G[i]); } //the second time, reverse writing. Cv.init (); for(inti=n-1; i>=1; i--) {Cv.add_line (-(i+1),-sum[i+1]); Tans= Max (Tans,cv.query (-g[i]) +sum[i]-(LL) i*G[i]); } cout<<ans+tans<<Endl; return 0;}
Convex hull trick CF344. E