Description
给出两个整数 \(μ\) 和 \(υ\),请你构造一个有 \(n\) 个元素的整数数列 \(A\),满足以下这些条件:
-
\(10\leqslant n\leqslant 1000\);
-
\(-10^9\leqslant A_i\leqslant 10^9\);
-
\(μ\) 恰好是 \(n\) 个整数的平均值;
-
\(υ\) 恰好是 \(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;
}