`
java-mans
  • 浏览: 11385740 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

转载请注明出处,谢谢http://blog.csdn.net/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]=p*phi(p^k-1)=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;
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics