欧拉函数
欧拉函数
定义:对于一个正整数 n ,小于 n 且和 n 互质的正整数(包括 1)的个数,记作 φ(n)
比如:n = 8 时,有 1,3,5,7 与它互质,所以 φ(8) = 4
函数计算公式:φ(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pn) ,其中p1,p2,...,pn位n的质因子
易知,如果n为质数,一定有 φ(n) = n-1
函数的几个性质:
1、φ(1)=1
2、φ(pk)=pk−pk−1=(p−1)⋅pk−1,其中p为质数
3、φ(mn)=φ(m)⋅φ(n),其中gcd(m,n)=1
欧拉定理:
若为正整数,且互素(即),则 。
换种说法就是 a^ φ(n) % n 恒等于 1.
特别的,当n是质数的时候,上式就变成了 ,它也叫费马小定理,但它是个单向定理,不能用这个同余证n是质数。
原根:
在时,定义对模的指数 为使 成立的最小的正整数。由欧拉定理知 一定小于等于 ,
若,则称是模的原根。
m的原根个数正好为φ(φ(m)) (在m是素数情况下进一步知原根的个数是φ(m-1) )
例:poj-1284 http://poj.org/problem?id=1284
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 #define N 1000005 7 int p[N]; 8 void fun(){ //素数表 9 int i, j, k; 10 memset(p, 0, sizeof(p)); 11 p[1] = 1; 12 for(i=2; i<=sqrt(N); i++){ 13 for(j=2; j<=N/i; j++){ 14 p[i*j] = 1; 15 } 16 } 17 } 18 int oula(int n){ 19 int i, j, r, a; 20 r = n; 21 a = n; 22 for(i=2; i<=sqrt(n); i++){ 23 if(!p[i]){ 24 if(a%i==0){ 25 r = r/i * (i-1); 26 while(a%i==0) 27 a /= i; 28 } 29 } 30 } 31 if(a>1) 32 r = r/a*(a-1); 33 return r; 34 } 35 36 int main(){ 37 int n; 38 while(cin>>n){ 39 // cout<<oula(oula(n))<<endl; //一般情况 40 cout<<oula(n-1)<<endl; //n为奇素数时 41 } 42 return 0; 43 }