POJ2478 Farey Sequence

本文详细介绍了如何通过欧拉函数计算序列F(n),并使用C++实现算法,解决从2到10万范围内的序列计算问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

http://poj.org/problem?id=2478

解题思路:

       通过观察,可以发现序列F(n)有以下特征:F(n-1)所具有的项,F(n)一定也具有。例如F(3)有1/3、1/2、2/3,F(4)也有这3项。所以我们关注的是F(n)与F(n-1)相比较所增加的项。最终我们可以了解到:F(n)与F(n-1)相比较,所增加的项的分母都是n,而分子与n互质。例如F(4)与F(3)相比较,增加的项是1/4、3/4。因此增加的项的数目是小于n且与n互质的数的个数,这些数的个数叫做欧拉函数。

       欧拉函数的一条计算公式是:ψ(n)=n*(1-1/p1)*(1-1/p2)*......*(1-1/pk),其中p1、p2、......、pk是n的质因子。例如6的质因子有2、3,所以ψ(6)=2。我们可以把ψ(n)的计算公式变换一下,便于程序的编写:ψ(n)=n*[(p1-1)/p1]*[(p2-1)/p2]*......*[(pk-1)/pk]。要想求出ψ(n),就必须知道n的所有质因子。而对于这道题目,我们要计算的是2~10万的ψ(n)是多少,我们可以通过跟筛选素数类似的方法一次性把所有的欧拉函数求出来。首先我们可以先令所有的ψ(n)=n,把公式中的第一个n先弄出来。然后从2开始,凡是能被2整除的数,它的ψ(n)都要除以2,并且乘上(2-1),因为2是它的质因子。同时,能被2整除的这些数就不能作为质因子去寻找能被它整除的数,例如,4能被2整除,4就不能作为质因子去寻找能被4整除的数。计算完能被2整除的数以后,就计算能被3整除的数,计算完能被3整除的数以后,就计算能被5整除的数,此时4已被剔除掉,以此类推。

       最终我们得到了所有的ψ(n),再根据递推关系计算F(n)。

具体代码:

#include<iostream>
#include<cstring>
#define MAXN 1000000
using namespace std;

long long phi[MAXN+1],F[MAXN+1];
bool vis[MAXN+1];

void calc()
{
    memset(vis,0,sizeof(vis));
    for(int i=2;i<=MAXN;i++)
        phi[i]=i;
    for(int i=2;i<=MAXN;i++)
        if(!vis[i])
            for(int j=i;j<=MAXN;j+=i)
            {
                phi[j]=phi[j]/i*(i-1);
                vis[j]=1;
            }
    F[2]=phi[2];
    for(int i=3;i<=MAXN;i++)
        F[i]=F[i-1]+phi[i];
}
int main()
{
    calc();
    int n;
    while(cin>>n&&n)
        cout<<F[n]<<endl;
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值