POJ2048 Longge's problem(积性函数)

题目链接:POJ2048

题意简述:给出一个整数N,求出 i 从1到 N 的所有 GCD(i,n) 的和。

解题思路:

将GCD(i,N)分为两个部分,即GCD(i,N)= 1与!=1。

  • GCD(i,N) = 1:从1到N所有与N互素的数有 phi(N) 个,而如果数 i 与 N互素,那么GCD(i,N) = 1,故该部分的和就求出来了,就是phi(N)。
  • GCD(i,N) != 1:假设GCD(i,N)= p;那么所有小于N的数中,尝试求出一共有多少个与N的最大公约数为 p 。N/p与N互素,小于 N/p 且与 N/p 互素的数 * p设为 j ,GCD(j,N)一定为p。所以GCD(i,N) = p 的数有 phi(N/p)个。

因此我们只需求出N的所有约数,即可求出最终答案。因为N的所有约数有对称性,故可以采用折半查找优化时间。

代码示例:

#include<cstdio>
typedef long long ll;
ll phi(ll n){
	ll ans = n;
	for(ll i = 2;i*i <= n;i++){
		if(n%i == 0) ans = ans/i*(i-1);
		while(n%i == 0)	n/=i;
	}
	if(n > 1)	ans = ans/n*(n-1);
	return ans;
}

int main(){
	ll n;
	while(scanf("%lld",&n) != EOF){
		ll ans = 0;
		for(ll i = 1;i*i <= n;i++){
			if(n % i == 0){
				ans += phi(n/i)*i;
				if(i * i < n)	ans += phi(i)*(n/i);
			}	
		}
		printf("%lld
",ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/long98/p/10352148.html