AcWing演算法基礎課 尤拉函式、快速冪
阿新 • • 發佈:2022-01-04
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全部尤拉函式的和View Code8 { 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 }
尤拉定理
若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
同樣還有遞迴的快速冪演算法。