P4983 忘情

题目描述

你的(npy)为了恶心你,特地请了四位大神和一个辣鸡!

( m hdxrie)说:“我们得求和。”于是有了(sumlimits_{i=1}^{n}x_i)

( m Imagine)说:“我们得有平均数。”于是有了(ar x)

( m TimeTraveller)说:“我们得有加减乘除。”于是有了一些恶心的组合。

( m Althen·Way·Satan)说:“我们还得有平方。”于是我们将它平方。

最垃圾的( m ZredXNy)说:“那我帮你们整合一下。”

于是,我们得到了这么一个式子(:)

(frac{left((sumlimits_{i=1}^{n}x_i×ar x)+ar x ight)^2}{ar x^2})

我们定义一段序列的值为这个,其中(n)为此序列的元素个数。

我们给定一段长度为(n)的序列,现在要求将它分成(m)段,要求每一段的值的总和最小,求出这个最小值。

题解

这道题神似P5308 [COCI2019] Quiz。

首先看到分成(k)段,很自然地可以想到(WQS)二分。

(frac{left((sumlimits_{i=1}^{n}x_i×ar x)+ar x ight)^2}{ar x^2})化简一下可得等于((sum_{i = 1} ^ {n}x_i + 1) ^ 2)

(f_i)表示到第(i)个数的最小价值和,很容易得到转移方程(f_i = min(f_i, f_j + (s_i - s_j + 1) ^ 2))

假设(k < j < i)(j)(k)优,可以化简得到(frac{f_j + s_j ^ 2 - (f_k + s_k ^ 2)}{s_j - s_k} <= 2 * (s_i + 1))

然后就(WQS)二分就好。

#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
const int N = 1e5 + 5;
const int ll inf = 1e15;
int n, m, a[N], g[N], q[N];
ll ans, f[N], s[N];
inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
ll Y(int x) {return f[x] + s[x] * s[x];}
ll X(int x) {return s[x];}
double slope(int i, int j) {return (double)(Y(i) - Y(j)) / (double)(X(i) - X(j));}
int check(ll mid)
{
	int l, r; q[l = r = 1] = 0;
	for(int i = 1; i <= n; i ++)
	{
		while(l < r && slope(q[l], q[l + 1]) <= 2.0 * (double)(s[i] + 1.0)) l ++;
		f[i] = f[q[l]] + (s[i] - s[q[l]] + 1) * (s[i] - s[q[l]] + 1) + mid; g[i] = g[q[l]] + 1;// + mid
		while(l < r && slope(q[r], q[r - 1]) >= slope(q[r - 1], i)) r --;
		q[++ r] = i;
	}
	return g[n] >= m;
}
void work()
{
	n = read(); m = read();
	for(int i = 1; i <= n; i ++) {a[i] = read(); s[i] = s[i - 1] + a[i];}
	ll l = -inf, r = inf;
	while(l <= r)
	{
		ll mid = (l + r) >> 1;
		if(check(mid)) ans = mid, l = mid + 1;
		else r = mid - 1;
	}
	check(ans); printf("%lld
", f[n] - ans * m);
}
int main() {return work(), 0;}
原文地址:https://www.cnblogs.com/Sunny-r/p/12625121.html