码迷,mamicode.com
首页 > 其他好文 > 详细

poj1284:欧拉函数+原根

时间:2014-09-12 22:05:44      阅读:294      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   for   div   sp   代码   log   

何为原根?
由费马小定理可知 如果a于p互质 则有a^(p-1)≡1(mod p)
对于任意的a是不是一定要到p-1次幂才会出现上述情况呢?
显然不是,当第一次出现a^k≡1(mod p)时, 记为ep(a)=k 当k=(p-1)时,称a是p的原根
每个素数恰好有f(p-1)个原根(f(x)为欧拉函数)
 
定理:对于奇素数m, 原根个数为phi(phi(m)), 由于phi(m)=m-1, 所以为phi(m-1)。
某大牛的证明:

{xi%p | 1 <= i <= p - 1} = {1,2,...,p-1} 等价于 {xi%(p-1) | 1 <= i <= p - 1} = {0,1,2,...,p-2},即为(p-1)的完全剩余系

若x,x2...x(p-1)是(p-1)的完全剩余系,

根据定理,可以推出若gcd(x, p-1) = 1时, (1,x,...,x(p-2))也是(p-1)的完全剩余系

因为若xi != xj (mod p-1),那么x*xi != x*xj (mod p-1),与条件m矛盾,所以 xi = xj (mod p-1),

由此可以确定答案为EulerPhi(p-1)

代码

#include<stdio.h>
#define maxn  66666
int euler[maxn+1];
int phi(int n)
{
    int res=n;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            res=res-res/i;
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)
        res=res-res/n;
    return res;
}
//筛法范围打表  nlogn
void phi()
{
    for(int i=1;i<=maxn;i++)
        euler[i]=i;
    for(int i=2;i<=maxn;i+=2)
        euler[i]/=2;
    for(int i=3;i<=maxn;i++)
    {
        if(euler[i]==i) //未被筛到。是素数,则用此素数来筛
        {
            for(int j=i;j<=maxn;j+=i)
            {
                euler[j]=euler[j]/i*(i-1);
            }
        }
    }
    return ;
}
int main()
{
    int n;
    phi();
    while(scanf("%d",&n)!=EOF)
    {
        printf("%d\n",euler[n-1]);
    }
}

 

poj1284:欧拉函数+原根

标签:style   blog   color   io   for   div   sp   代码   log   

原文地址:http://www.cnblogs.com/lnever/p/3969117.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!