BZOJ 2705: [SDOI2012]Longge的问题
2705: [SDOI2012]Longge的问题
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 2554 Solved: 1566
[Submit][Status][Discuss]
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。
Source
分析:
继续学数学...如果今天不GG,预计应该是高产的一天...然而题目难度2333...
根据Dirichlet卷积:id(i)=i,id=φ×1,(f×g)=Σ(d|n)f(d)*g(n/d)
Σ(1<=i<=n) gcd(i,n)
=Σ(1<=i<=n) id(gcd(i,n))
=Σ(1<=i<=n) Σ(d|gcd(i,n))φ(d)
=Σ(d|n)φ(d)*n/d
代码:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 //by NeighThorn 7 #define int long long 8 using namespace std; 9 //大鹏一日同风起,扶摇直上九万里 10 11 int n,m,ans; 12 13 inline int phi(int x){ 14 int cnt=x; 15 for(int i=2;i<=m;i++) 16 if(x%i==0){ 17 cnt=cnt/i*(i-1); 18 while(x%i==0) 19 x/=i; 20 } 21 if(x>1) 22 cnt=cnt/x*(x-1); 23 return cnt; 24 } 25 26 signed main(void){ 27 scanf("%lld",&n); 28 m=sqrt(n);ans=0; 29 for(int i=1;i<=m;i++) 30 if(n%i==0){ 31 ans+=phi(i)*n/i; 32 if(n/i>m) 33 ans+=phi(n/i)*i; 34 } 35 printf("%lld\n",ans); 36 return 0; 37 }
by NeighThorn