【欧拉函数】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 }

 

posted @ 2015-06-19 00:14  CyanNode  阅读(155)  评论(0编辑  收藏  举报