poj2480 Longge's problem

欲求 (sum_{i=1}^n (i,n))

显然 ((i,n) mid n)。记 (d=(i,n)),枚举 (d),有多少个 (i in [1,n]) 使得 ((i,n)=d) 呢?换句话说有多少个 (i in [1,lfloor n/d floor]) 使得 ((i,lfloor n/d floor) = 1) 呢?显然是 (varphi(lfloor n/d floor)) 个。

答案就是 (sum_{d|n}dcdot varphi(n/d))

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
ll n, T;
ll ans;
ll phi(ll x){
	ll re=x;
	for(ll i=2; i*i<=x; i++)
		if(x%i==0){
			re = re / i * (i - 1);
			while(x%i==0)	x /= i;
		}
	if(x>1)	re = re / x * (x - 1);
	return re;
}
int main(){
	while(scanf("%d", &n)!=EOF){
		ans = 0;
		for(ll i=1; i*i<=n; i++)
			if(n%i==0){
				ans += (ll)i * phi(n/i);
				if(i*i!=n)	ans += (ll)(n/i) * phi(i);
			}
		printf("%lld
", ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/8550168.html