poj 2478 Farey Sequence(欧拉函数)

来源:互联网 发布:优酷福利待遇 知乎 编辑:程序博客网 时间:2024/05/16 02:45
F2 = {1/2}F3 = {1/3, 1/2, 2/3}F4 = {1/4, 1/3, 1/2, 2/3, 3/4}F5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5} 

先来说明下题意。告诉一直特定的序列,就是上面那一种,然后告诉你一个正整数n,求出Fn有多少项。

先看上面的序列,可以发现分子跟分母都是不可约分的,对!例如分子为a,分母为b。gcd(a,b)=1。肯定有同学会想的gcd。

但是我们有欧拉函数。

然后就是简单的求欧拉函数的题目了。

有一点要注意的是,由于连续用到了求欧拉函数的值,所以这里用到了打表。以前求欧拉函数的方法用在这里一定会超时的。

下面先看看递推打表求欧拉函数的代码

void Eular()/*打表存phi值*/{    for(int i = 1; i <= maxn ; i++)phi[i] = i;/*预先置所有数的欧拉函数值为其本身*/    for(int i = 2 ; i <= maxn ; i+=2) phi[i]/=2; /*偶数项可以先约一个2*/    for(int i = 3 ; i <= maxn ; i+=2 )    {        if(i == phi[i])/*如果p是一个正整数且∮(p) = p-1,那么p是素数*/        {            for(int j = i ; j <= maxn ; j+=i)/*遇到这种情况,把这个数的欧拉值改变,同时也把能被该因子整除的数改变*/            {                phi[j] = phi[j]/i*(i-1);            }        }    }    for(int i = 3 ; i <= 1000000 ; i++)    {        phi[i] += phi[i-1];    }}


下面是完整代码

#include<cstdio>#include<iostream>using namespace std;const int maxn = 1000010;long long phi[maxn+1];/*因为使用数组是从下标1开始的,所以在创建的时候要多开几位,不然会Runtime error*/int main(){    void Eular();    int n;    Eular();    while(cin>>n && n)    {        cout<<phi[n]<<endl;    }    return 0;}void Eular()/*打表存phi值*/{    for(int i = 1; i <= maxn ; i++)phi[i] = i;/*预先置所有数的欧拉函数值为其本身*/    for(int i = 2 ; i <= maxn ; i+=2) phi[i]/=2; /*偶数项可以先约一个2*/    for(int i = 3 ; i <= maxn ; i+=2 )    {        if(i == phi[i])/*如果p是一个正整数且∮(p) = p-1,那么p是素数*/        {            for(int j = i ; j <= maxn ; j+=i)/*遇到这种情况,把这个数的欧拉值改变,同时也把能被该因子整除的数改变*/            {                phi[j] = phi[j]/i*(i-1);            }        }    }    for(int i = 3 ; i <= 1000000 ; i++)    {        phi[i] += phi[i-1];    }}


原创粉丝点击