题目描述
题意
给定三个数n,l,r,构建一个n个数的数组(下标从1到n)满足数组中每一个数 l ≤ a i ≤ r l ≤ a_i ≤ r l≤ai≤r且 g c d ( i , a i ) gcd(i,a_i) gcd(i,ai)各不相同。
思路
这是一道思维题;
要保证
g
c
d
(
i
,
a
i
)
gcd(i, a_i)
gcd(i,ai)各不相同,通过暴力会发现一定满足
g
c
d
(
i
,
a
i
)
=
i
gcd(i, a_i)=i
gcd(i,ai)=i,因此
a
i
a_i
ai是
i
i
i的倍数,且
a
i
a_i
ai在范围
[
l
,
r
]
[l, r]
[l,r]中,因此问题转换成在[
l
,
r
]
l,r]
l,r]中寻找
i
i
i的倍数。因此即找
l
l
l之后第一个
i
i
i的倍数;要求一个数
x
≥
l
x≥l
x≥l的第一个倍数,可以推出这个式子来求:
(
(
l
+
x
−
1
)
/
x
)
∗
x
((l+x-1)/x)*x
((l+x−1)/x)∗x(注意是整除);因此可以找到
i
i
i的倍数为
(
(
l
+
i
−
1
)
/
i
)
∗
i
((l+i-1) / i) * i
((l+i−1)/i)∗i,再判断这个数是否在
[
l
,
r
]
[l,r]
[l,r]范围内即可。
总结
这道题首先要能发现 g c d ( i , a i ) = i gcd(i,a_i)=i gcd(i,ai)=i,我在做这道题过程中通过暴力发现了这个性质,但是没想到 a i a_i ai是 i i i的倍数,还是太菜了(哭)
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
int t, n, l, r;
int a[N];
int ans[N];
int gcd(int a, int b)
{
if(b == 0) return a;
return gcd(b, a % b);
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> t;
while(t -- )
{
cin >> n >> l >> r;
bool ok = true;
for(int i = 1; i <= n; i ++ )
{
int x = ((l + i - 1) / i) * i;
if(x > r)
{
ok = false;
break;
}
ans[i] = x;
}
(ok) ? cout << "YES" << endl : cout << "NO" << endl;
if(ok)
{
for(int i = 1; i <= n; i ++ )
cout << ans[i] << ' ';
cout << endl;
}
}
return 0;
}