POJ 2480 Longge's problem 解题报告(欧拉函数 + 积性函数)
2014-04-27 08:58
393 查看
Longge's problem
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 Source POJ Contest,Author:Mathematica@ZSU |
这样是可以A的,代码如下:
#include <cmath> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; int epi(int n) { int ret=n; for(int i=2; i*i<=n; i++) if(n%i==0) { ret=ret/i*(i-1); while(n%i==0) n/=i; } if(n>1) ret=ret/n*(n-1); return ret; } LL num[7000]; int main() { int n; while(~scanf("%d", &n)) { int t=0; LL i; for(i=1; i*i<=n; i++) if(n%i==0) num[t++]=i, num[t++]=n/i; if(t>=2 && num[t-1]==num[t-2]) t--; if(t==2) { printf("%lld\n", (long long)n*2-1); continue; } LL ans=0; for(i=0; i<t; i++) ans=ans+num[i]*epi(n/num[i]); printf("%lld\n", ans); } }
但是有更好更通用的做法。
首先我们要证明在函数F(N) = ∑gcd(i, N)中,如果M,N互质,那么F(M*N)=F(M)*F(N).
如何证明呢?我看到的一个完整的证明过程:http://hi.baidu.com/bfcdygoporbjuxr/item/f119741c5fcd9c48e75e06e0
简单来说,就是这样:
F(M*N)=∑gcd(i, M*N)=∑∑gcd(i*M+j*N, M*N)=∑∑gcd(i,
N)*gcd(j, M)=∑gcd(i, N)*∑gcd(j, M)=F(M)*F(N)
证明了这个过程之后,我们可以对n进行因式分解,分解成n=p1^e1 * p2^e1 * p3^e3 ... * pn^en的形式,那么pi之间两两互质,得到F(n)=F(p1^e1)*F(p2^e2)...*F(pn^en)。
接下来求F(p^e)=即可。F(N) = ∑gcd(i, p^e)。p^e的约数有p^0,
p^1, p^2, ..., p^e,枚举因数,整理公式,可得:
F(p^e) = e*p^(e-1)*(p-1)+p^e。
至此,可以求出F(n)了。代码如下:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
int pp[40];
int ee[40];
int tol;
void decomposition(int n)
{
tol=0;
int m=sqrt(n)+0.5;
for(int i=2;i<=m;i++) if(n%i==0)
{
int t=0;
while(n%i==0) n/=i, t++;
pp[tol]=i, ee[tol]=t, tol++;
}
if(n>1) pp[tol]=n, ee[tol]=1, tol++;
}
int power(int a, int b)
{
int res=1;
while(b)
{
if(b&1)
res=res*a;
a=a*a;
b>>=1;
}
return res;
}
int main()
{
int n;
while(~scanf("%d", &n))
{
decomposition(n);
LL ans=1;
for(int i=0;i<tol;i++)
{
int p=pp[i], e=ee[i];
ans=ans*power(p, e-1)*((LL)e*(p-1)+p);
}
printf("%lld\n", ans);
}
}
相关文章推荐
- POJ 2480 Longge's problem(积性函数之欧拉函数与gcd)
- poj 2480 Longge's problem(积性函数 & 欧拉函数)
- POJ 2480 Longge's problem(欧拉函数,积性函数)
- poj 2480 Longge's problem(欧拉函数或积性函数)
- 【poj】 2480 Longge's problem (欧拉函数)
- POJ 2480 Longge's problem (欧拉函数)
- POJ 2480 Longge's problem (积性函数,欧拉函数)
- POJ 2480 Longge's problem (欧拉函数)
- poj 2480 Longge's problem 积性函数性质+欧拉函数
- POJ 2480 Longge's problem 欧拉函数
- POJ2480 Longge's problem 欧拉函数应用
- POJ 2480 Longge's problem 欧拉函数的应用 积性函数
- POJ 2480 Longge's problem(神奇欧拉函数)
- (poj 2480 Longge's problem)<欧拉函数>
- poj 2480 Longge's problem(欧拉函数的性质)
- POJ 2048 Longge's problem (欧拉函数 积性函数)
- POJ2480——Longge's problem(数论,欧拉函数d)
- poj 2480 Longge's problem 关于欧拉函数和积形函数推导
- POJ 2480 Longge's problem 积性函数
- POJ Longge's problem 积性函数