【欧拉函数】BZOJ2705: [SDOI2012]Longge的问题
Description
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
Solution
如果我们考虑每个gcd的贡献
那么k作为约数的贡献就是k*phi(n/k)
于是只需要枚举约数计算phi就行了
然而这好像是暴力=v=
然而约数也不可能很多
这么打也非常快
另:从这里也可以推出Σ[d|n]φ(d)=n
考虑phi函数计算
感觉可以考虑pi的贡献
然而我并是理不太清于是弃疗了
官方题解的确是这样:http://www.cnblogs.com/JS-Shining/archive/2012/05/14/2500661.html
各种专有名词云云感觉真要是遇到了也就只能凭感觉蒙一蒙了
Code
枚举约数的技巧是只枚举到sqrt(n),大约数可由小约数得到
一般phi计算sqrt(n),搞出素数表可以更快
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #define ll long long 5 using namespace std; 6 7 ll n,ans; 8 9 ll phi(ll x){ 10 ll ret=x; 11 for(ll i=2;i*i<=x;i++) 12 if(x%i==0){ 13 ret=(ret/i*(i-1)); 14 while(x%i==0) x/=i; 15 } 16 if(x>1) ret=ret/x*(x-1); 17 return ret; 18 } 19 20 int main(){ 21 scanf("%lld",&n); 22 for(ll i=1;i*i<=n;i++) 23 if(n%i==0){ 24 ans+=i*phi(n/i); 25 if(i*i<n) ans+=(n/i)*phi(i); 26 } 27 printf("%lld\n",ans); 28 return 0; 29 }