[省选前题目整理][POJ 2407]Relatives(欧拉函数)

来源:互联网 发布:vr设备 知乎 编辑:程序博客网 时间:2024/06/06 21:03

题目链接

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

题目大意

给出n,求欧拉函数ϕ(n)

思路

有两种做法:
1、O(n)线性筛法,适合n很小但是求欧拉函数次数很多的地方。由于此题n过大因此会TLE。
2、根据欧拉函数公式分解n的质因数,适合n比较大但是求欧拉次数很少的地方,适合本题。

代码

1、O(n)线性筛

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#define MAXN 1000using namespace std;bool isPrime[MAXN];int fai[MAXN]; //欧拉函数int prime[MAXN],tot=0; //质数void GetEular(){    memset(isPrime,true,sizeof(isPrime));    fai[1]=1;    tot=0;    for(int i=2;i<MAXN;i++)    {        if(isPrime[i])        {            prime[++tot]=i;            fai[i]=i-1;        }        for(int j=1;j<=tot;j++)        {            if(i*prime[j]>MAXN) break;            isPrime[i*prime[j]]=false;            if(i%prime[j]==0)            {                fai[i*prime[j]]=fai[i]*prime[j];                break;            }            else                fai[i*prime[j]]=fai[i]*(prime[j]-1);        }    }}int main(){    GetEular();    int n;    while(scanf("%d",&n)!=EOF&&n)    {        printf("%d\n",fai[n]);    }    return 0;}

2、分解n的质因数

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#define MAXN 1000using namespace std;int fai(int n){    int ans=n;    for(int i=2;i<=n;i++)    {        if(n%i==0)        {            ans=ans/i*(i-1);            while(n%i==0) n/=i;        }    }    return ans;}int main(){    int n;    while(scanf("%d",&n)!=EOF&&n)    {        printf("%d\n",fai(n));    }    return 0;}
0 0