Slope optimization
F[i]=max (f[j]+s[j]* (S[i]-s[j]))
Make g[i]=f[i]-s[i]^2
J-Better than K-merit so g[j]+s[i]s[j]>g[k]+s[i][k]
G[j]-g[k]>s[i] (S[k]-s[j])
g[j]-g[k]/(S[j]-s[k]) <-s[i]
So the maintenance queue can be convex
#include <iostream>#include<cstdio>#include<queue>#defineMAXN 100000#include<cstring>#definell Long Longusing namespacestd;intRead () {intx=0, f=1;CharCh=GetChar (); while(ch<'0'|| Ch>'9'){if(ch=='-') f=-1; ch=GetChar ();} while(ch>='0'&&ch<='9') {x=x*Ten+ch-'0'; Ch=GetChar ();} returnx*F;} intn,k;int from[202][maxn+5];ll F[MAXN+5];ll S[MAXN+5];ll g[2][maxn+5];intq[maxn+5];inttop=0, tail=1; llGet(intPreintXintt) { while(top-tail>=1&& (g[pre][q[tail]]-g[pre][q[tail+1]]) <s[x]* (s[q[tail+1]]-S[q[tail])) ++tail; from[T] [x]=Q[tail]; returng[pre][q[tail]]+s[q[tail]]*s[x];};voidInsintTintk) { while(top-tail>=1) { inti=q[top-1],j=Q[top]; if((G[t][k]-g[t][j]) * (S[i]-s[j]) < (G[t][j]-g[t][i]) * (S[j]-s[k])) top--; Else Break; } q[++top]=K;}intMain () {//freopen ("sequence.in", "R", stdin); //freopen ("Sequence.out", "w", stdout);N=read (); k=read (); for(intI=1; i<=n;i++) {S[i]=read (); s[i]+=s[i-1]; } intPre=0, nown=1; for(intI=1; i<=n;i++) g[pre][i]=-(s[i]*S[i]); for(intL=2; l<=k+1; l++) {memset (F,0,sizeof(f)); top=0; tail=1; memset (G[nown],0,sizeof(G[nown])); INS (pre,l-1); for(inti=l;i<=n;i++) {F[i]=Get(pre,i,l); G[nown][i]=f[i]-(s[i]*S[i]); if(s[i]!=s[i-1]) ins (pre,i); //printf ("%d%d%i64d\n", L,i,from[l][i],f[i]);} nown=1-Nown; Pre=1-Pre; } printf ("%lld\n", F[n]); return 0;}
[APIO2014] Sequence Segmentation