2705: [SDOI2012]Longge的问题
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1275 Solved: 820
[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
掉到莫比乌斯反演的坑里无法自拔,问了zyf&在网上看了题解才做出来TAT……我果然好弱
这个题是要求$\sum_{x=1}^{n}gcd(x,n)$,考虑它的实际意义,我们可以得到$ans=\sum_{i|n}i*\varphi(\frac{n}{i})$
但是明显φ函数我们是没法预处理的……($\frac{n}{i}$这玩意太大了),但考虑到n的约数不会太多,所以我们可以边找因数边计算φ。
1 /************************************************************** 2 Problem: 2705 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:16 ms 7 Memory:804 kb 8 ****************************************************************/ 9 10 //BZOJ 2705 11 #include<cmath> 12 #include<cstdio> 13 #define F(i,j,n) for(int i=j;i<=n;i++) 14 typedef long long LL; 15 LL phi(LL n){ 16 int ret=1,i; 17 for(int i=2;i*i<=n;i++){ 18 if (n%i==0){ 19 n/=i; ret*=i-1; 20 while(n%i==0) n/=i,ret*=i; 21 } 22 } 23 if (n>1) ret*=n-1; 24 return ret; 25 } 26 int main(){ 27 int n; 28 scanf("%d",&n); 29 long long ans=0; 30 for(int i=1;i*i<=n;i++) 31 if(n%i==0){ 32 ans+=(LL)i*phi(n/i); 33 if (i*i<n) ans+=(LL)n/i*phi(i); 34 } 35 printf("%lld\n",ans); 36 return 0; 37 }