题解:CF2246B ezraft and Array
考虑归纳构造。令 \(S_k = \sum_{i=1}^k a_i\)。假设已经构造好了 \(k-1\) 个互不相同的正整数 \(a_1,a_2,\dots,a_{k-1}\),并且满足条件:对任意 \(1 \le i \le k-1\),都有 \(a_i \mid S_{k-1}\)。
现在我们添加第 \(k\) 个数,令 \(a_k = S_{k-1}\)。此时新的总和为 \(S_k = S_{k-1} + a_k = 2S_{k-1}\)。
对于原有的 \(a_i\ (i < k)\),由归纳假设 \(a_i \mid S_{k-1}\),自然有 \(a_i \mid 2S_{k-1} = S_k\)。
对于新加入的 \(a_k\),\(a_k = S_{k-1} \mid 2S_{k-1} = S_k\)。
因此所有 \(k\) 个数都满足条件。同时,由于 \(S_{k-1}\) 严格大于前面已出现的所有数,\(a_k\) 不会与已有元素重复。
这便给出了一种从 \(k-1\) 到 \(k\) 的合法扩展方法。
基础情况
- \(n = 1\):任意一个正整数即可,例如输出 \(1\)。
- \(n = 2\):无解。证明:设两个互异正整数 \(a,b\) 满足 \(a \mid (a+b)\) 且 \(b \mid (a+b)\)。由 $a \mid (a+b) $ 得出 $ a \mid b$,同理 \(b \mid a\),故 \(a = b\),与互异矛盾。
- \(n = 3\):可取 \(a = [1, 2, 3]\)。总和 \(S_3 = 6\),显然 \(1\mid6,\ 2\mid6,\ 3\mid6\)。
一般情况(\(n \ge 4\))
从基础解 \([1,2,3]\) 开始,反复使用上述归纳扩展:
\(a_1=1,\ a_2=2,\ a_3=3\);对于 \(i \ge 4\),令 \(a_i = S_{i-1}\)。
此时序列为 \(1,\ 2,\ 3,\ 6,\ 12,\ 24,\ \dots\),通项为 \(a_i = 6 \times 2^{i-4}\ (i \ge 4)\)。
当 \(n \le 50\) 时,最大的元素出现在 \(i=n=50\),即 \(a_{50} = S_{49} = 3 \times 2^{47} \approx 4.2 \times 10^{14}\),远小于题目限制的 \(10^{17}\),不会溢出。
时间复杂度 \(O(Tn)\)。
代码
#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define int long long
using namespace std;
const int N=100020;
int n;
signed main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
if(n==1){puts("1");continue;}
if(n==2){puts("-1");continue;}
if(n==3){puts("1 2 3");continue;}
printf("1 2 3 ");
int res=6;//S3=6
fo(i,4,n)
{
printf("%lld ",res);
res*=2;
}
puts("");
}
return 0;
}

浙公网安备 33010602011771号