Description

给出两个整数 \(μ\)\(υ\),请你构造一个有 \(n\) 个元素的整数数列 \(A\),满足以下这些条件:

  1. \(10\leqslant n\leqslant 1000\)

  2. \(-10^9\leqslant A_i\leqslant 10^9\)

  3. \(μ\) 恰好是 \(n\) 个整数的平均值;

  4. \(υ\) 恰好是 \(n\) 个整数的方差。

Solution

首先,我们将 \(n\) 乘过去,就是平方和了。

我们发现,要使平均数为 \(μ\),我们构造的数必须是:\(μ+a,μ+b,μ+c\) 这种形式。(保证 \(a+b+c==0\))但这样还是不好构造。

其实我们直接将这种关系转化为两两匹配的就行了。可以知道,这样匹配的最低效益是 \(2\)(加一和减一)。所以,只要我们保证 \(v*n\) 是偶数就一定可以这样凑出来。那我们直接选偶数 \(n\) 就行了。

另外,这题看上去数据很大,其实用刚刚的匹配方法,每次选最大的效益,凑出来的数的个数是不会超出范围的。(每次减去一个在自己范围内最大的完全平方数的两倍)

不妨构造 \(\mu+\delta,\mu-\delta\) 这样的数字加入数列,这样就只用考虑 \(υ\) 是方差的限制。可以发现这样一对数字的贡献是 \(2\delta^2\),于是对 \(υ\) 进行分解,每次减去最大的 \(2\delta^2\),事实上这个缩减速度是很快的 —— 考虑这样一个不等式

\[2\delta ^2\leqslant υ,2(\delta+1)^2>υ \]

可以得到 \(υ-4\delta-2<2\delta^2\leqslant υ\),也就是说,\(υ\)\(\delta^2\) 的级别变成了 \(\delta\) 的级别。

Code

#include<cmath>
#include<cstdio>

int T, u, len, n = 20;
long long v, tmp, num[100];

int read() {
	int x = 0, f = 1; char s;
	while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
	while(s >= '0' && s <= '9') {
		x = (x << 1) + (x << 3) + (s ^ 48);
		s = getchar();
	}
	return x * f;
}

int main() {
	freopen("math.in", "r", stdin);
	freopen("math.out", "w", stdout);
	T = read();
	while(T --) {
		u = read(), v = read(); v *= n;
		len = 0;
		for(int i = 1; i <= n; ++ i) num[i] = u;
		while(v) {
			tmp = sqrt(v >> 1);
			num[++ len] = u - tmp, num[++ len] = u + tmp;
			v -= (tmp * tmp << 1);
		}
		printf("%d\n", n);
		for(int i = 1; i <= n; ++ i) printf("%lld%c", num[i], (i == n ? '\n' : ' '));
	}
	return 0;
} 
posted on 2020-08-24 14:41  Oxide  阅读(109)  评论(0编辑  收藏  举报