欧拉函数 模板
欧拉函数
定义(by Wikipedia)
在数论中,对正整数n,欧拉函数{\displaystyle \varphi (n)}是小于或等于n的正整数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为φ函数(由高斯所命名)或是欧拉总计函数[1](totient function,由西尔维斯特所命名)。
例如{\displaystyle \varphi (8)=4},因为1,3,5,7均和8互质。
性质
一、当 N > 2 时, Φ( N ) 为偶数.
二、当 N 为素数时,Φ( N ) = N-1;
三、Cn 的所有子群都具有 Cd 的形式,其中d整除n(记作d | n)。因此只要考察n的所有因数d,将 Cd 的生成元个数相加,就将得到 Cn 的元素总个数:n。也就是说:
其中的d为n的正约数。
四、若:p是素数,且 n = p^k,那么φ(n) = (p-1)*p^(k-1)
五、对任何两个互质的正整数a, m(即 gcd(a,m) = 1),,有
即欧拉定理。
六、若:p, q互质,那么:φ(p*q) = φ(p) * φ(q)
七、一个数 x 的所有质因数的和 φ( x )*x/2
模板
1 #include <bits/stdc++.h> 2 #define INF 0x3f3f3f3f 3 #define LL long long 4 using namespace std; 5 const int MAX = 1e5; 6 const int MAXN = 1e5+10; 7 int mark[MAXN]; 8 int pri[MAXN]; 9 int tot; 10 int euler[MAXN]; 11 ///欧拉函数公式:euler(x) = x*(1-1/p1)(1-1/p2)……(1-1/pn),p为x的质因数。 12 LL Euler(LL n) //单独求 N 的欧拉函数值 13 { 14 LL res = n; 15 for(LL i = 2; i*i <= n; i++){ 16 if(n%i == 0) res = res/i*(i-1); 17 while(n%i == 0) n/=i; 18 } 19 if(n > 1) res = res/n*(n-1); 20 return res; 21 } 22 23 void Euler_B() //打表求 1~MAX 的欧拉函数值 24 { 25 euler[1]=1; 26 for(int i=2;i<MAX;i++) 27 euler[i]=i; 28 for(int i=2;i<MAX;i++) 29 if(euler[i]==i) 30 for(int j=i;j<MAX;j+=i) 31 euler[j]=euler[j]/i*(i-1); 32 } 33 34 ////////////////////////////////////////////// 35 ////线性时间内筛欧拉函数和素数////// 36 ///////////////////////////////////////// 37 bool com[MAXN]; 38 int primes, prime[MAXN], phi[MAXN]; 39 void get_phi(int n){ 40 phi[1] = 1; 41 for (int i = 2; i <= n; ++i) 42 { 43 if (!com[i]) 44 { 45 prime[primes++] = i; 46 phi[i] = i-1; 47 } 48 for (int j = 0; j < primes && i*prime[j] <= n; ++j) 49 { 50 com[i*prime[j]] = true; 51 if (i % prime[j]) 52 phi[i*prime[j]] = phi[i]*(prime[j]-1); 53 else 54 { phi[i*prime[j]] = phi[i]*prime[j]; break; } 55 } 56 } 57 } 58 /////////////////////////////////////// 59 int main() 60 { 61 int N; 62 Euler_B(); 63 scanf("%d", &N); 64 65 printf("%lld\n", Euler(N)); 66 printf("%d\n", euler[N]); 67 68 get_phi(N); 69 printf("%d\n", phi[N]); 70 return 0; 71 }