1. 程式人生 > 其它 >AcWing演算法基礎課 尤拉函式、快速冪

AcWing演算法基礎課 尤拉函式、快速冪

1、尤拉函式的定義是,φ(n)是1-n中與n互質的數的個數

對n分解質因數得p1^a1*p2^a2*...*pn^an,

則φ(n)=n*(1-1/p1)(1-1/p2)*...*(1-1/pn);

對多個數求尤拉函式,可以結合線性篩法,對每個質數和被篩到的數,都根據已經被迴圈到的數的φ計算

 1 const int N = 100010;
 2 int primes[N], cnt;
 3 int phi[N];//全部尤拉函式
 4 bool not_prime[N];//是否為質數
 5 typedef long long LL;
 6 
 7 LL get_eulers(int n)//求1-n全部尤拉函式的和
8 { 9 phi[1] = 1; 10 for (int i = 2; i <= n; i++) 11 { 12 if (!not_prime[i]) 13 { 14 primes[cnt++] = i; 15 phi[i] = i - 1;//質數的尤拉函式 16 } 17 for (int j = 0; primes[j] <= n / i; j++) 18 { 19 not_prime[primes[j] * i] = true
; 20 if (i%primes[j] == 0) 21 { 22 phi[primes[j] * i] = phi[i] * primes[j]; //primes[j] * i的最小質因子為primes[j],且primes[j]是i的質因子 23 break; 24 } 25 phi[primes[j] * i] = phi[i] * (primes[j] - 1); 26 //primes[j] * i的最小質因子為primes[j],且primes[j]不是i的質因子(primes[j]-1)=primes[j]*(1-1/primes[j])
27 } 28 29 } 30 LL res = 0; 31 res = accumulate(phi + 1, phi + n + 1, 0LL); 32 return res; 33 }
View Code

尤拉定理

若a與n互質,則有 (a^φ(n))%n=1;

2、快速冪

對a^k,可以預處理出,a^(2^0),a^(2^1)...,a^(2^n),其中a^(2^(n+1))>k,a^(2^(n))≤k。其中a^(2^(i+1))=(a^(2^i))^2,O(logn)

則k=x0*(2^0)+x1*(2^1)+...+xn*(2^n),其中xi為k的二進位制表示的第i位,取0或1

則a^k=a^(x0*(2^0))*a^(x1*(2^1))*...*a^(xn*(2^n)),O(logn)。

演算法結果取模則每步預處理也取模。

 1 int qmi(int a, int k, int p)//(a^k)%p
 2 {
 3     int res=1;
 4     while (k)
 5     {
 6         if (k & 1) res = (LL)(res*a) % p;//a初始為a^(2^0)=a
 7         k >> 1;
 8         a = (LL)a*a%p;
 9     }
10     return res;
11 }
View Code

同樣還有遞迴的快速冪演算法。