# bzoj1911: [Apio2010]特别行动队

### 题目链接

bzoj1911: [Apio2010]特别行动队

### 题解

$f_i = max(f_j+A(S_i-S_j)^2+B(S_i-S_j)+C)$

#### 直接推呀:

$j<k$$j$$k$优。

$f_j+A(S_i-S_j)^2+B(S_i-S_j)+C>f_k+A(S_i-S_k)^2+B(S_i-S_k)+C$

$f_j-f_k+A(2S_i-S_j-S_k)*(S_k-S_j)+B(S_k-S_j)>0$

$f_j+S_j^2-2AS_iS_j-BS_j >f_k+S_k^2-2AS_iS_k-BS_k$

$G_j=f_j+AS_j^2-BS_j$,$H_j=-2AS_j$

$\frac{G_j-G_k}{H_j-H_k}<-S_i$

### 代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
LL x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9'){ if(c == '-')f = -1; c = getchar();}
while(c <= '9' && c >= '0')x = x * 10 + c - '0',c = getchar();
return x * f;
}

const int maxn = 1000007;
LL n,a,b,c;
LL sum[maxn];
LL dp[maxn];
LL Y (int i) { return dp[i] + a * sum[i] * sum[i] - b * sum[i]; }
LL X (int i) { return  sum[i]; }
double slop(int i,int j)  { return 1.0 * (Y(i) - Y(j)) / (X(i) - X(j));  }
int q[maxn];
int main() {
for(int i = 1;i <= n;++ i) sum[i] = read() + sum[i - 1];
for(int l = 0,r = 0,i = 1;i <= n;++ i)  {
while(l < r && slop(q[l],q[l + 1]) > 2 * a * sum[i])l ++;
//dp[i] = dp[q[l]] + a * (sum[i] - sum[q[l]]) * (sum[i] - sum[q[l]]) + b * (sum[i] - sum[q[l]] + c);
dp[i] = -(2 * a * sum[i] * X(q[l]) - Y(q[l]) - a * sum[i] * sum[i] - b * sum[i] - c);
while(l < r && slop(q[r - 1],q[r]) <= slop(q[r],i)) r --;
q[++ r] = i;
}
printf("%lld\n",dp[n]);
return 0;
}


posted @ 2018-06-26 19:44  zzzzx  阅读(94)  评论(0编辑  收藏  举报