bzoj2705 [SDOI2012]Longge的问题
Description
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
Input
一个整数,为N。
Output
一个整数,为所求的答案。
Sample Input
6
Sample Output
15
HINT
【数据范围】
对于60%的数据,0<N<=2^16。
对于100%的数据,0<N<=2^32。
正解:欧拉函数。
我想到杜教筛和莫比乌斯函数上去了。。想了好久都没想出来。。
我们考虑一下,对于$n$的一个因子$k$,满足$\gcd(n,i)=k$的数有多少个。那么既然$gcd(n,i)=k$,那么$gcd(\frac{n}{k},\frac{i}{k})=1$,于是我们找出小于等于$\frac{n}{k}$的数,且与它互质的数的个数,那这就是欧拉函数。直接用欧拉函数公式$\phi(n)=n*(1-\frac{1}{p_{1}})*(1-\frac{1}{p_{2}})*...*(1-\frac{1}{p_{K}})$求出来就行了。
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <complex> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cstdio> 8 #include <vector> 9 #include <cmath> 10 #include <queue> 11 #include <stack> 12 #include <map> 13 #include <set> 14 #define il inline 15 #define RG register 16 #define ll long long 17 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 18 19 using namespace std; 20 21 ll n,m,ans; 22 23 il ll phi(RG int n){ 24 RG ll x=n; 25 for (RG ll i=2;i<=m;++i){ 26 if (n%i) continue; 27 x=x/i*(i-1); 28 while (!(n%i)) n/=i; 29 } 30 if (n>1) x=x/n*(n-1); return x; 31 } 32 33 il void work(){ 34 cin>>n; m=sqrt(n); 35 for (RG ll i=1;i<=m;++i){ 36 if (n%i) continue; 37 ans+=i*phi(n/i); 38 if (i<n/i) ans+=(n/i)*phi(i); 39 } 40 cout<<ans; return; 41 } 42 43 int main(){ 44 File("longge"); 45 work(); 46 return 0; 47 }