Set $c[i]=g[i]+\frac{i (i+1)}{2}-a[i]\times i-a[i]$, $d [i]=a[i]-i$
$f [i]$ indicates the maximum number of buildings to keep at the end of $i$, then
$f [I]=\max (F[j]) +1$, $j <i and D[j]\leq d[i]$
$g [i]$ represents the minimum cost at the end of $i$, the
$g [I]=\min (I\times d[j]+c[j]) +b[i]+a[i]+\frac{i (i-1)}{2}$, $j <i,f[j]+1=f[i] and D[j]\leq d[i]$
According to a group of $f$, each group is sorted by ordinal, and then treated.
When divided, according to $d$ sort, with the stack maintenance convex shell, query on the convex hull two points.
Time complexity $o (N\LOG^2N) $.
#include <cstdio> #include <algorithm> #define N 100010using namespace Std;typedef long Long ll;int n,m,i,j,k, A[n],b[n],d[n],e[n],bit[n],f[n],ans0,g[n],nxt[n];int Cl,cr,l[n],r[n],top,q[n];ll c[N],g[N],ans1=1LL<<62; struct E{int x,t; E () {}e (int _x,int _t) {x=_x,t=_t;}} h[n];inline void Read (int&a) {char c;while (!) ( ((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')); a=c-' 0 '; while (((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')) (a*= Ten) +=c-' 0 ';} inline void Umax (Int&a,int b) {if (a<b) a=b;} inline void Umin (Ll&a,ll b) {if (a>b) a=b;} inline int lower (int x) {int l=1,r=n+1,mid,t; while (l<=r) if (e[mid= (l+r) >>1]<=x) l= (t=mid) +1;else r=mid-1; return t;} inline void ins (int x,int y) {for (; x<=n+1;x+=x&-x) Umax (bit[x],y);} inline int Ask (int x) {int t=-n;for (; x;x-=x&-x) Umax (t,bit[x]); return t;} inline void Add (int x,int y) {nxt[y]=g[x]; G[x]=y;} inline BOOL cmp (int x,int y) {return d[x]==d[y]?c[x]>c[y]:d [x]<d[y];} Inline double pos (int x,int y) {return 1.0* (C[y]-c[x])/(D[x]-d[y]);} inline void Insert (int x) {if (Top&&d[x]==d[q[top]]) top--; while (Top>1&&pos (q[top],x) >pos (Q[top],q[top-1])) top--; Q[++top]=x;} inline void query (int x) {if (!top) return; int l=1,r=top-1,mid,t=top; while (l<=r) {mid= (l+r) >>1; if (X>pos (q[mid],q[mid+1])) r= (t=mid) -1;else l=mid+1; } umin (G[x],1ll*x*d[q[t]]+c[q[t]);} void Solve (int l,int r) {if (l==r) return; int mid= (L+R) >>1,i,j; Solve (L,mid), Solve (mid+1,r); for (cl=0,i=l;i<=mid;i++) if (!h[i].t) l[++cl]=h[i].x; for (cr=0,i=r;i>mid;i--) if (h[i].t) r[++cr]=h[i].x; if (!cl| |! CR) return; Sort (l+1,l+cl+1,cmp), sort (r+1,r+cr+1,cmp); for (i=j=1,top=0;i<=cr;i++) {while (J<=cl&&d[l[j]]<=d[r[i]) insert (l[j++]); Query (R[i]); }}int Main () {read (n); for (i=1;i<=n;i++) read (A[i]); for (i=1;i<=n;i++) read (B[i]), e[i+1]=d[i]=a[i]-i; Sort (e+1,e+n+2); for (i=1;i<=n+1;i++) bit[i]=-n; INS (lower (0), 0); for (i=1;i<=n;i++) G[i]=ans1,j=lower (d[i]), Ins (J,f[i]=ask (j) +1); Ans0=ask (n+1); for (i=0;i<=n;i++) g[i]=-1; for (i=n;~i;i--) if (f[i]>=0) Add (f[i],i); for (i=0;i<ans0;i++) {j=g[i],k=g[i+1],m=0; while (~j| | ~k) {if (j<0) h[++m]=e (k,1), k=nxt[k]; else if (k<0| | j<k) h[++m]=e (j,0), j=nxt[j]; else H[++m]=e (k,1), k=nxt[k]; } solve (1,m); for (K=g[i+1];~k;k=nxt[k]) {g[k]+=b[k]+a[k]+1ll*k* (k-1)/2; c[k]=g[k]+1ll*k* (k+1)/2-1ll*a[k]*k-a[k]; }} for (i=0;i<=n;i++) if (F[I]==ANS0) umin (ans1,g[i]+1ll* (n-i) *a[i]+1ll* (n-i) * (n-i+1)/2); Return printf ("%d%lld", ans0,ans1), 0;}
BZOJ2149: Demolition Team