POJ 2480 Longge's problem(神奇欧拉函数)

本文介绍了一种高效算法来求解∑gcd(i,N),1≤i≤N的问题。通过分解N的所有因子d,并利用欧拉函数的性质,避免了重复计算,最后给出了实现该算法的C++代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处,谢谢 http://blog.youkuaiyun.com/ACM_cxlove?viewmode=contents           by---cxlove

http://poj.org/problem?id=2480

给出N,求 ∑gcd(i, N) 1<=i <=N. 

推导太犀利了。

首先对于每一个N的因子d,如果gcd(m,n)=d,那我们需要找出有多少这样的m,其实这步比较简单就是d*phi(n/d)。

也许会想,为什么不是n/.d个呢,应该有n/d个都是d的倍数,拥有d这个因子。考虑如果与n/d不互质的一个数乘以d,和n的最大公约数必定不是d,那么就会重复计算,欧拉函数的神奇应用。

由于N比较大,也不适合枚举所有因子,也许打出素数表加上快速求eular可以水过。

先要了解eular函数的一个性质。

phi(p^k)=(p-1)*p^(k-1)

考虑如果N=P^k的时候,那么F[N]=k*p^(k-1)+p^k。

利用eular的积性性质

F[N]=F[p1^k1*p2^k2……pi^ki]=(ki*pi^(ki-1)+p^ki).

接下来对于N进行因式分解。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define LL long long
#define MOD 1000000007
using namespace std;
int main(){
	LL n;
	while(scanf("%lld",&n)!=EOF){
		LL ans=1;
		for(LL i=2;i*i<=n;i++)
			if(n%i==0){
				LL k=0,p=1;
				while(n%i==0){
					k++;
					p*=i;
					n/=i;
				}
				ans*=k*(p-p/i)+p;
			}
		if(n>1)
			ans*=2*n-1;
		printf("%lld\n",ans);
	}
	return 0;
}


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值