f[i]=max{f[j]+(i-j-1)*i-(b[i-1]-b[j])+a[i]}b[i]为i的前缀和
易得(f[j]+b[j]-f[k]-b[k])/(j-k)<i
同样单调队列维护凸包
longlong老是没注意,AC率就是这么刷下来的QAQ
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 1000000+5 10 using namespace std; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 14 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 15 return x*f; 16 } 17 int n,a[NM],q[NM],qh,qt; 18 ll f[NM],b[NM]; 19 double slope(int x,int y){ 20 return (double)(f[y]+b[y]-f[x]-b[x])/(y-x); 21 } 22 int main(){ 23 freopen("data.in","r",stdin); 24 n=read(); 25 inc(i,1,n)a[i]=read(); 26 inc(i,1,n)b[i]=b[i-1]+i; 27 // inc(i,1,n)printf("%d ",b[i]);printf("\n"); 28 qh=qt=1;q[1]=0; 29 inc(i,1,n){ 30 while(qh+1<=qt&&slope(q[qh],q[qh+1])<i)qh++; 31 int j=q[qh]; 32 f[i]=f[j]+(ll)(i-j-1)*i-b[i-1]+b[j]+a[i]; 33 while(qh+1<=qt&&slope(q[qt-1],q[qt])>=slope(q[qt],i))qt--; 34 q[++qt]=i; 35 } 36 // inc(i,1,n)printf("%d ",f[i]);printf("\n"); 37 printf("%lld\n",f[n]); 38 return 0; 39 }