AtCoder Regular Contest 163

C - Harmonic Mean

题意

要求构造一个长度为 nn 的一个数组 aa,满足以下条件:

  • i=1n1ai=1\sum\limits_{i=1}^n\dfrac{1}{a_i}=1
  • aa 中的元素各不相同
  • 1ai1091\leq a_i\leq 10^9

题解

利用 1k(k+1)=1k1k+1\dfrac{1}{k(k+1)}=\dfrac{1}{k}-\dfrac{1}{k+1} 可以进行构造:11×2,12×3,1(n1)×n,1n\dfrac{1}{1\times 2},\dfrac{1}{2\times3},\cdots\dfrac{1}{(n-1)\times n},\dfrac{1}{n}。但是,1n\dfrac{1}{n} 有可能和前面某一项重复,即 n=k×(k+1)n=k\times (k+1)

此时,我们构造 a=(2,2a1,2a2,,2an1)a=(2,2a_1',2a_2',\cdots,2a_{n-1}'),其中 aia_i'n1n-1 时的解,容易验证它是符合限制的。

可能会有人问为什么不直接都采取第二种构造方式。原因是它的增长速度太快,会超出 10910^9 的范围。而能表示成 k×(k+1)k\times (k+1) 的数是不连续的,所以上述构造方式可以保证 aia_i 在限制范围内。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <bits/stdc++.h>
using namespace std;
vector<int> v[505];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
for(int i=3;i<=500;i++)
{
bool ok=1;
for(int k=1;k<i;k++)
{
v[i].push_back(k*(k+1));
if(i==k*(k+1)) ok=0;
}
if(ok) v[i].push_back(i);
else
{
v[i].clear();
v[i].push_back(2);
for(int k=0;k<i-1;k++) v[i].push_back(2*v[i-1][k]);
}
}
int t;cin>>t;
while(t--)
{
int n;cin>>n;
if(n==1)
{
cout<<"Yes"<<'\n';
cout<<1<<'\n';
}
else if(n==2) cout<<"No"<<'\n';
else
{
cout<<"Yes"<<'\n';
for(int i=0;i<n;i++) cout<<v[n][i]<<" \n"[i==n-1];
}
}
return 0;
}

AtCoder Regular Contest 163
https://je3ter.github.io/2023/07/03/ACM/AtCoder Regular Contest 163/
作者
Je3ter
发布于
2023年7月3日
许可协议