扩展欧拉函数

欧拉函数


 


     对正整数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。


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



求单个数的欧拉函数

题意:给你一个数n,n很大(n<=100000000),但是题目中的测试数据不是很多,这样的话直接用求单个欧拉函数值的方法求解,如果用下面第二种方法打个表的话是行不通的,因为n的值太大不适合开设数组,所以这时应该直接求n的欧拉函数值。

//直接求解欧拉函数 

 int euler(int n){ //返回euler(n)     

   int res=n,a=n;     

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

  if(a%i==0){            

   res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出              

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

   }    

   }  

     if(a>1) res=res/a*(a-1);  

     return res; 

 }  

  //筛选法打欧拉函数表  

 #define Max 1000001 

 int euler[Max];  

void Init(){     

    euler[1]=1;   

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

    euler[i]=i;    

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

    if(euler[i]==i)         

    for(int j=i;j<Max;j+=i)           

     euler[j]=euler[j]/i*(i-1);//先进行除法是为了防止中间数据的溢出   

}




题目描述

对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler's totient function、φ函数、欧拉商数等。例如:φ(8) = 4(Phi(8) = 4),因为1,3,5,7均和8互质。

现在让你求Phi(Phi(n))。


输入

输入一个数N。(2 <= N <= 10^9)

输出

输出 Phi(Phi(n))。

样例输入

8

样例输出

2
#include<iostream>
#include<cstdio>
#include<cmath>
#define maxn 1000010
using namespace std;
int phi[maxn];
int euler(int n){
	int res=n,a=n;
	for(int i=2;i*i<=a;i++){
		if(a%i==0){
			res=res/i*(i-1);
			while(a%i==0) a/=i; 
		}
	}
	if(a>1) res=res/a*(a-1);
	return res;
}
int main(){
	int n;
	while(cin >> n){
		printf("%d\n",euler(euler(n)));
	}
	return 0;
}

 

你可能感兴趣的:(扩展欧拉函数)