ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[APIO2010]特别行动队

2020-09-17 13:03:30  阅读:230  来源: 互联网

标签:slope 特别 int APIO2010 long ++ lld% 行动队 lld


解析

转移方程很容易推:\(f_i = \max(f_j + a * (s_i - s_j)^2 + b * (s_i - s_j) + c)\)
然后当 \(j>k\) 时,如果 \(j\) 更优
那么 \(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 + a * s_j^2 - b * s_j) - (f_k + a * s_k^2 - b * s_k) > 2 * a * s_i * (s_j-s_k)\)
因为 \(s_j-s_k\) 大于零
所以我们可以把不等式两边同除 \(s_j-s_k\) (不除 \(2*a\),当然也可以除,但注意 \(a < 0\),除过去要变号)
于是就成了 \(\frac{(f_j + a * s_j^2 - b * s_j) - (f_k + a * s_k^2 - b * s_k)}{s_j-s_k} > 2 * a * s_i\)
既然是大于号,那么维护上凸壳
右边单调减,单调队列维护即可

\(Code\)

#include<cstdio>
using namespace std;
typedef long long LL;

const int N = 1e6 + 5;
int n , l , r;
LL a , b , c , f[N] , q[N] , s[N];

double slope(int u , int v)
{ 
	return 1.0 * ((f[u] + a * s[u] * s[u] - b * s[u]) - (f[v] + a * s[v] * s[v] - b * s[v])) 
		/ (s[u] - s[v]);
}

int main()
{
	scanf("%d%lld%lld%lld" , &n , &a , &b , &c);
	for(register int i = 1; i <= n; i++) scanf("%lld" , &s[i]) , s[i] += s[i - 1];
	q[l = r = 1] = 0;
	for(register int i = 1; i <= n; i++)
	{
		while (l < r && slope(q[l] , q[l + 1]) > 2.0 * a * s[i]) l++;
		f[i] = f[q[l]] + a * (s[i] - s[q[l]]) * (s[i] - s[q[l]]) + b * (s[i] - s[q[l]]) + c;
		while (r >= l && slope(q[r] , q[r - 1]) < slope(q[r] , i)) r--;
		q[++r] = i;
	}
	printf("%lld" , f[n]);
}

标签:slope,特别,int,APIO2010,long,++,lld%,行动队,lld
来源: https://www.cnblogs.com/leiyuanze/p/13684501.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有