欧拉函数模板

对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。例如euler(8)=4,因为1,3,5,7均和8互质。   

Euler函数表达通式:euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn为x的所有素因数,x是不为0的整数。

euler(1)=1(唯一和1互质的数就是1本身)。    

欧拉公式的延伸:一个数的所有质因子之和是euler(n)*n/2。

那么如何变成实现欧拉函数呢?下面通过两种不同的方法来实现。第一种方法是直接根据定义来实现,同时第一种方法也是第二种筛法的基础,当好好理解。

 1  1 //直接求解欧拉函数
 2  2 int euler(int n){ //返回euler(n) 
 3  3      int res=n,a=n;
 4  4      for(int i=2;i*i<=a;i++){
 5  5          if(a%i==0){
 6  6              res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出 
 7  7              while(a%i==0) a/=i;
 8  8          }
 9  9      }
10 10      if(a>1) res=res/a*(a-1);
11 11      return res;
12 12 }
13 13 
14 14 //筛选法打欧拉函数表 
15 15 #define Max 1000001
16 16 int euler[Max];
17 17 void Init(){ 
18 18      euler[1]=1;
19 19      for(int i=2;i<Max;i++)
20 20        euler[i]=i;
21 21      for(int i=2;i<Max;i++)
22 22         if(euler[i]==i)
23 23            for(int j=i;j<Max;j+=i)
24 24               euler[j]=euler[j]/i*(i-1);//先进行除法是为了防止中间数据的溢出 
25 25 }
26 View Code
int euler(int n)//返回euler(n)

{

     int i;

     int res = n,a = n;

     for(i = 2;i*i <= a; ++i)

     {

         if(a%i == 0)

         {

             res -= res/i; //p(n) = (p - p/p1)(1 - 1/p2)......

             while(a%i == 0) a/=i;

         }

     }

     if(a > 1) res -= res/a;//存在大于sqrt(a)的质因子

     return res;

} 


  

欧拉函数打表:








void SE()//select euler//类似于素数筛选法

{

    int i,j;

    euler[1] = 1;

    for(i = 2;i < Max; ++i)  euler[i]=i;

    for(i = 2;i < Max; ++i)

    {

         if(euler[i] == i)//这里出现的肯定是素数

         {

           for(j = i; j < Max; j += i)//然后更新含有它的数

           {

              euler[j] = euler[j]/i*(i - 1); // n*(1 - 1/p1)....*(1 - 1/pk).先除后乘

           }

        }

    }

     //for (int i = 1; i <= 20; ++i) printf("%d ",euler[i]);

} 
原文地址:https://www.cnblogs.com/CrazyBaby/p/5703436.html