暑期训练2 I题
传送门:http://poj.org/problem?id=2480
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 8072 | Accepted: 2669 |
Description
"Oh, I know, I know!" Longge shouts! But do you know? Please solve it.
Input
A number N per line.
Output
Sample Input
2 6
Sample Output
3 15
题意:给你一个数n,求出从1到n所有数与n的最大公约数的和。
题解:通过欧拉定理来做。
首先说一下φ(n),即表示小于等于n的与n互质的数的个数,φ(1)即为1。
而欧拉定理则指出φ(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pn),期中p1,p2,...为n的质因数。
由上面的式子可以得到对于质数a,φ(a^b)=(a^b)*(1-1/a)=(a-1)*a^(b-1)。
对于∑GCD(i,a^b),可以发现他等于φ(a^b)+a*φ(a^(b-1))+...+(a^b)*φ(1)即为b*(a-1)*(a^(b-1))+a^b
(此处解释一下∑GCD(i,a^b)可以分成i与a^b的gcd为1,a,...,a^b,而其相应的个数分别为φ(a^b),φ(a^(b-1))...φ(1))
同时对于∑GCD(i,a^b*c^d)=∑GCD(i,a^b)*∑GCD(i,c^d)
(这一点可以理解成与a^b存在最大公约数的每个数分别同c^d所有最大公约数组合了一遍)
因此最后我们可以发现对于任意的N=a^b*c^d*...*y^z
∑GCD(i,N)=(b*(a-1)*(a^(b-1))+a^b)*(d*(c-1)*(c^(d-1))+c^d)*...*(z*(y-1)*(y^(z-1))+y^z)
下面附上代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<math.h>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
int main()
{
long long n,ans,i,k,sum;
while(~scanf("%lld",&n))
{
ans=1;
for(i=2;i*i<=n;i++)
{
sum=0;
k=1;
while(n%i==0)
{
n=n/i;
sum++;
k=k*i;
}
ans*=sum*(k-k/i)+k;
}
if(n!=1) ans*=2*n-1;
printf("%lld\n",ans);
}
return 0;
}