您的位置:首页 > 产品设计 > UI/UE

poj 2478 Farey Sequence(基于素数筛法欧拉函数)

2016-11-01 15:27 429 查看
题意:

求第n个farey 序列中元素的个数

第n个farey序列中的元素为分子分母小于等于n,且不能约分了的分数。

思路:

第n个序列中,包含分母从2到n的分数,要求不能被约分的分数个数,可以分别求出2到n中每个数有多少个小于它本身与它互质的数,再加和即可。求小于n的与n互质的数最快的办法是欧拉函数,调用下即可。

基于素数筛法求欧拉函数的原理:

设a是n的质因数,若(N%a == 0 && (N/a)%a == 0) 则 φ(N) = φ(N/a)*a; 若(N%a == 0 && (N/a)%a != 0) 则φ(N) = φ(N/a)*(a-1)。(φ(N)
即小于n的与n互质的数的个数)。前者可以看做一个递归过程。

代码:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=1e6+5;
int prim[maxn];
bool pri[maxn];
int phi[maxn];
long long ans[maxn];
void get_phi()
{
int i, j;
phi[1]=1; //1的欧拉函数是1
int k=0;
for(i=2; i<=maxn; i++)
{
if(!pri[i])
{
prim[++k]=i;
phi[i]=i-1;
}
for(j=1; j<=k && prim[j]*i<=maxn; j++)
{
pri[i*prim[j]]=1;
if(i%prim[j]==0)
{
phi[i*prim[j]]=phi[i]*prim[j];
}
else phi[i*prim[j]]=phi[i]*(prim[j]-1);
}
}
}
int main()
{
get_phi();
int n;

ans[1]=0;
for(int i=2; i<=maxn; i++)
{
ans[i]=ans[i-1]+phi[i];
}
while(~scanf("%d", &n))
{
if(n==0)break;

printf("%lld\n", ans
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: