POJ-20407Relatives/NYOJ-333mdd的烦恼,欧拉函数简单应用,模板A

来源:互联网 发布:188旅游网站源码 编辑:程序博客网 时间:2024/05/21 10:02
 poj                         Relatives                               

Time Limit: 1000MS Memory Limit: 65536K   微笑吐舌头大笑奋斗       微笑吐舌头大笑奋斗

                                                                            
                                                                             ->  题目连接 <-
     题目就不用占地方了,以后都用链接来吧;
     这道题就是一个欧拉函数的应用,学了欧拉函数应该没什么问题,但欧拉函数需要注意的是如果题目没有明确要求的话euler(1)的值一般是1;
     欧拉函数用来求解1-n-1中与n互质的数的数目,类似于素数问题,先将所要求的数m分解质因数为p1,p2,p3....,这些质因数两两不等,则euler(m)=m*(1-1/Pi),累加符号不会,将就看看;
     博主也是看了好久,虽然还没下定决心开始研究数论大笑,不过学妹jian问了问这个问题,奈何没学过,就让人家去找学长了................
void fun(int x){    int ans=x,n=x;    for(int i=2;i*i<=n;i++)        if(n%i==0)    {        ans-=ans/i;就相当于a*(1-1/p);        while(n%i==0)            n/=i;    }    if(n>1) ans-=ans/n;    printf("%d\n",ans);}//感觉这个函数效率还是蛮高的;int main(){    int n;    while(~scanf("%d",&n)&&n)    {        fun(n);    }    return 0;}




nyoj                                        mdd的烦恼                                          

时间限制:1000 ms  |  内存限制:65535 KB
难度:3


                                                                             ->  题目链接  <-

          nyoj上的这道题和上面的简直一模一样,只不过题目所给的数据范围很大,用long long 可以表示,但是欧拉函数不会超时吗?当然不会,前面已经提到过这个效率特别高,65535的平方也即是表明程序只能跑到65535,多者超出范围,数据全用long long 表示,我们注意,这个n也是一直在减小的,所以更不用担心超时了,把上面的程序全部改成long long 便可以了;
void fun(long long x){    long long ans=x,n=x;    for(long long i=2; i*i<=n; i++)        if(n%i==0)        {            ans-=ans/i;            while(n%i==0)                n/=i;        }    if(n>1) ans-=ans/n;    printf("%lld\n",ans);}int main(){    long long n;    while(~scanf("%lld",&n)&&n)    {        fun(n);    }    return 0;}//这里就不再赘述了;




   下面来介绍一下欧拉函数筛法打表,类似于素数打表,十分精简;
const int N=1000000+10;int euler[N];void Init( ){    memset(euler,0,sizeof(euler));    euler[1]=1;//初始化1,请注意根据实际情况做出更改;    for(int i=2; i<N; i++)        if(!euler[i])        {            for(int j=i; j<N; j+=i)//类似于素数筛法打表;            {                if(!euler[j])                    euler[j]=j;                euler[j]-=euler[j]/i;//关键;            }        }}int main(){    int n;    Init();    while(~scanf("%d",&n)&&n)    {        printf("%d\n",euler[n]);    }    return 0;}

  

0 0