洛谷P1592 互质

【分析】:

这一题我们显然不能使用暴力枚举每一个数、同时计数的方法,因为题目给的数据太大了,暴力计数显然超时,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;
}

好了,今天的分享就到这里,感谢观看,如果喜欢,记得关注哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值