您的位置:首页 > 其它

POJ 2480

2016-07-21 00:05 411 查看
暑期训练2 I题

传送门:http://poj.org/problem?id=2480

Longge's problem

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 8072 Accepted: 2669
Description

Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N. 

"Oh, I know, I know!" Longge shouts! But do you know? Please solve it. 

Input

Input contain several test case. 

A number N per line. 

Output

For each N, output ,∑gcd(i, N) 1<=i <=N, a line
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: