http://acm.hdu.edu.cn/showproblem.php?pid=3507
解释:当且仅当g【j,k】程璐,j对dp【i】的更新由于k对dp【i】的;
解释:对于第2点,因为单调队列维护的要是斜率上升的数据结构;所以要做此循环
对于第3点,因为是斜率上升的数据结构,所以如果满足持续有条件成立,就会一直优下去,知道条件不满足(就好像bst里的前驱一样)
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; inline ll read(){ ll sum=0,x=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') x=0; ch=getchar(); } while(ch>='0'&&ch<='9') sum=(sum<<1)+(sum<<3)+(ch^48)*1ll,ch=getchar(); return x?sum:-sum; } inline void write(ll x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } const int M=5e5+5; ll dp[M],a[M]; int que[M],n,m; ll ans(int i,int j){ return dp[j]+(a[i]-a[j])*(a[i]-a[j])+m; } ll zi(int i,int j){ return dp[i]+a[i]*a[i]-(dp[j]+a[j]*a[j]); } ll mu(int i,int j){ return (a[i]-a[j]); } int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;i++){ a[i]=read(); a[i]+=a[i-1]; } dp[0]=a[0]=0; que[1]=0; int head=1,tail=1; for(int i=1;i<=n;i++){ while(head+1<=tail&&zi(que[head+1],que[head])<=2ll*a[i]*mu(que[head+1],que[head])) head++; dp[i]=ans(i,que[head]); while(head+1<=tail&&zi(i,que[tail])*mu(que[tail],que[tail-1])<=zi(que[tail],que[tail-1])*mu(i,que[tail])) tail--; que[++tail]=i; } write(dp[n]); putchar('\n'); } return 0; }