【分析】:
这一题我们显然不能使用暴力枚举每一个数、同时计数的方法,因为题目给的数据太大了,暴力计数显然超时,10^8还是太大。暴力计数不行,这时我们注意到n的数据较小,那么我们何不暴力n、通过n以内与n互质的数和n以外与n互质的数之间的规律求解呢?
以10为例,和它互质的数有1,3,7,9,11,13,17,19,21,23......
我们可以对其进行分组:
1,3,7,9
11,13,17,19
21,23,27,29
. . . . . .
不难发现:这些数具有很强的周期性,而且n就是周期
1,3,7,9 【1-10】 内与10互质的数 第0周期
11,13,17,19 【11-20】内与10互质的数 第1周期
21,23,27,29 【21-30】内与10互质的数 第2周期
. . . . . .
这也就是说:从1开始,每连续n个数里与n互质的数的数量是一定的
即,我们用数组记住这个周期就可以解决问题。
C++代码:
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int gcd(int m, int n)//辗转相除法求最大公约数
{
int r = 1;
while (r)
{
r = m % n;
m = n;
n = r;
}
return m;
}
int T[N];
int main()
{
int n, k, cnt = 0;
cin >> n >> k;
for(int i=1;i<n;i++)//记录一个周期内与n互质的数
if (gcd(i, n) == 1)//gcd(i, n) == 1即为二者互质
T[++cnt] = i;
// k/cnt表示第几个周期,乘以周期n,再加上剩下的即为答案
cout << k / cnt * n + T[k - k/ cnt * cnt] << endl;
return 0;
}
好了,今天的分享就到这里,感谢观看,如果喜欢,记得关注哦!