歐拉函數 線性篩 快速冪 逆元 中國剩餘定理 exgcd

快速冪

快速冪是對倍增思想的應用,可以以 log\log 級別的複雜度求 aka^k

kk 爲偶數,則 ak=ak2×ak2a^k = a^{\frac{k}{2}} \times a^{\frac{k}{2}}

kk 爲奇數,則 ak=a1×ak1a^k = a^1 \times a^{k-1}。奇數減一爲偶數。

int ksm(int a, int k, int p) {
  	int res = 1;
  	while (k) {
    	if (k & 1) res = res * a % p;
    	a = a * a % p;
    	k >>= 1;
  	}
  	return res % p;
}

線性篩

線性篩質數可求 1n1 \sim n 所有的質數。

對於每一個數 ii,標記所有小於 「ii 的最小質因子」 的質數 ×i\times i 的數爲合數。如 i=77=7×11i=77=7 \times 11,那麼 2×77, 3×77, 5×772 \times 77, \ 3\times 77, \ 5 \times 77 會標記爲合數。

想證明該算法爲線性且正確,只需證明沒有重複篩,沒有多篩,沒有漏篩三點即可。其中沒有重複篩顯然成立。

令一個合數 x=j=1npjpj<pj+1x = \prod _{j=1}^n p_j \land p_j < p_{j+1}

篩掉該合數的機會爲 i=j=1npjpjx=pj×j=1npjpji = \frac{\prod _{j=1}^n p_j}{p_j} \land x = p_j \times \frac{\prod _{j=1}^n p_j}{p_j} 。因爲標記所有小於 「ii 的最小質因子」 的質數 ×i\times i 的數爲合數,所以 j=1j = 1。沒有重複篩成立。

j=1npjp1<x\frac{\prod _{j=1}^n p_j}{p_1} < x,所以 i=j=1npjp1i = \frac{\prod _{j=1}^n p_j}{p_1} 時將 xx 標記爲合數。沒有漏篩成立。

int pr[N + 5], vis[N + 5] = {1, 1}, n, tot;
void init() {
	for (int i = 1; i <= N; i++) {
		if (!vis[i]) pr[++tot] = i;
		for (int j = 1; j <= tot && i * pr[j] <= N; j++) {
			vis[i * pr[j]] = 1;
			if (i % pr[j] == 0) break; 
		}
	}
} 

exgcd

擴展歐幾里得求形如 ax+by=cax + by = c 的方程。

  • 對於不爲 00 的整數 a,ba,b,存在整數 x,yx,y,使得 ax+by=gcd(a,b)ax + by = gcd(a,b)

  • 方程 ax+by=cax + by = c 有解,當且僅當 gcd(a,b)cgcd(a,b)|c

特殊情況:對於 ax+by=gcd(a,b)ax + by = gcd(a,b),當 b=0b = 0 時,令 x=1,y=0x = 1, y = 0 即求得一組解。

一般情況:借鑑輾轉相除法 gcd(a,b)=gcd(b,amodb)gcd(a,b)=gcd(b,a \bmod b),假設已經求得了 (bmoda)x0+ay0=gcd(a,b)(b \bmod a) x_0+ay_0=gcd(a,b) 的一組解 (x0,y0)(x_0, y_0),方程可以根據 amodm=amama \bmod m=a-m\left \lfloor \frac{a}{m} \right \rfloor 變形爲

(baba)x0+ay0=gcd(a,b) (b-a\left \lfloor \frac{b}{a} \right \rfloor)x_0+ay_0=gcd(a,b)

bax0+ay0+bx0=gcd(a,b) \left \lfloor \frac{b}{a} \right \rfloor x_0 + ay_0 + bx_0 = gcd(a,b)

a(y0bax0)+bx0=gcd(a,b) a(y_0-\left \lfloor \frac{b}{a} \right \rfloor x_0)+bx_0=gcd(a,b)

交換 x0x_0y0y_0
a(x0bay0)+by0=gcd(a,b) a(x_0-\left \lfloor \frac{b}{a} \right \rfloor y_0)+by_0=gcd(a,b)

{ax+by=gcd(a,b)a(x0bay0)+by0=gcd(a,b)    {x=x0y0bay=y0 \begin{cases} ax + by = gcd(a,b) \\ a(x_0-\left \lfloor \frac{b}{a} \right \rfloor y_0)+by_0=gcd(a,b) \end{cases} \iff \begin{cases} x=x_0-y_0\left \lfloor \frac{b}{a} \right \rfloor \\ y=y_0 \\ \end{cases}

int exgcd(int a, int b, int &x, int &y) { 
    if (a == 0) {
        x = 0, y = 1;
        return b;
    }
    int d = exgcd(b % a, a, y, x);
    x -= b / a * y;
    return d;
}

如何求最小正整數解。假設我們求出了
ax0+by0=gcd(a,b) ax_0+by_0 = gcd(a,b)
的一組解 (x0,y0)(x_0, y_0)。有解的必要條件爲 gcd(a,b)cgcd(a,b)|c,所以令 k=cgcd(a,b)k = \frac{c}{gcd(a,b)}
ax+by=c ax + by = c

ax+by=k×gcd(a,b) ax + by = k \times gcd(a,b)

{axk+byk=gcd(a,b)ax0+by0=gcd(a,b)    {x=k×x0y=k×y0    {x=cgcd(a,b)×x0y=cgcd(a,b)×y0 \begin{cases} a \frac{x}{k} + b \frac{y}{k} = gcd(a,b) \\ ax_0 + by_0 = gcd(a,b) \end{cases} \iff \begin{cases} x = k \times x_0 \\ y = k \times y_0 \end{cases} \iff \begin{cases} x = \frac{c}{gcd(a,b)} \times x_0 \\ y = \frac{c}{gcd(a,b)} \times y_0 \end{cases}

a×cgcd(a,b)×x0+b×cgcd(a,b)×y0=c a \times \frac{c}{gcd(a,b)} \times x_0 + b \times \frac{c}{gcd(a,b)} \times y_0 = c

爲了求最小整數解,需要把上式的 x0x_0 儘可能地減小,如果 x0x_0 減小,對應的 y0y_0 會增加。所以設 x0x_0 減小了 t0t_0y0y_0 增加了 t1t_1
{x=x0×cgcd(a,b)cgcd(a,b)×t0y=y0×cgcd(a,b)+cgcd(a,b)×t1a×x0×cgcd(a,b)a×cgcd(a,b)×t0+b×y0×cgcd(a,b)+b×cgcd(a,b)×t1=ca×cgcd(a,b)×x0+b×cgcd(a,b)×y0=ca×cgcd(a,b)×t0=b×cgcd(a,b)×t1t0t1=b×cgcd(a,b)a×cgcd(a,b)t0t1=ba \begin{cases} x = x_0 \times \frac{c}{gcd(a,b)} - \frac{c}{gcd(a,b)} \times t_0 \\ y = y_0 \times \frac{c}{gcd(a,b)} + \frac{c}{gcd(a,b)} \times t_1 \end{cases} \\ \Downarrow \\ a \times x_0 \times \frac{c}{gcd(a,b)} - a \times \frac{c}{gcd(a,b)} \times t_0 + b \times y_0 \times \frac{c}{gcd(a,b)} + b \times \frac{c}{gcd(a,b)} \times t_1 = c\\ \because a \times \frac{c}{gcd(a,b)} \times x_0 + b \times \frac{c}{gcd(a,b)} \times y_0 = c \\ \therefore a \times \frac{c}{gcd(a,b)} \times t_0 = b \times \frac{c}{gcd(a,b)} \times t_1 \\ \frac{t_0}{t_1} = \frac{b \times \frac{c}{gcd(a,b)}}{a \times \frac{c}{gcd(a,b)}} \\ \frac{t_0}{t_1} = \frac{b}{a}

a(x0t0)+b(y0+t1)=c    a(x0t0)+b(y0+ab×t0) a (x_0 - t_0) + b(y_0 + t_1) = c \iff a(x_0 - t_0) + b(y_0 +\frac{a}{b} \times t_0 )

t0=bgcd(a,b)t_0 = \frac{b}{gcd(a,b)},將 x0x_0 減到不能再減爲止,並考慮 bgcd(a,b)<0\frac{b}{gcd(a,b)} < 0 的情況需要加上模數再取模。總結公式爲
{xmin=(x0modbgcd(a,b)+bgcd(a,b))modbgcd(a,b)ymin=ca×x0b \begin{cases} x_{min}=(x_0 \bmod \frac{b}{gcd(a,b)} + \frac{b}{gcd(a,b)}) \bmod \frac{b}{gcd(a,b)} \\ y_{min} = \frac {c – a \times x_0}{b} \end{cases}


逆元

逆元與除法取模有關,具體的,如果 abmodm=a×xmodm\frac{a}{b} \bmod m = a \times x \bmod m,我們把 xx 叫作 bb 在模 mm 意義下的逆元,記做 b1b^{-1}。有
b×x1(modm) b \times x \equiv 1\pmod{m}

求質數逆元常見的方式是費馬小定理。 如果模數 pp 爲一個質數,而整數 aa 不是 pp 的倍數,則有
ap11(modp)ap2a1(modp) a^{p-1} \equiv 1\pmod{p} \\ \Updownarrow \\ a^{p-2} \equiv a^{-1} \pmod{p}
所以 aa 的逆元爲 ap2a^{p-2}

如果模數 mm 不爲質數,但 bbmm 互質,那麼可以用擴展歐幾里得求逆元。因爲擴展歐幾里得可以求線性同餘方程
b×x1(modm)b×xmodm=1bx+(my)=1 b \times x \equiv 1\pmod{m} \\ \Updownarrow \\ b \times x \bmod m = 1 \\ \Updownarrow \\ bx + (- my) = 1

exgcd 求解即可。


歐拉函數

歐拉函數的符號爲 φ\varphiφ(n)\varphi(n) 爲小於等於 nnnn 互質的數的個數。

對於一個質數 pp 和一個整數 kk,有
φ(p)=p1φ(pk)=pkpkk=pkpk1 \varphi(p) = p - 1 \\ \varphi(p^k) = p^k - \frac{p^k}{k} = p ^k - p^{k-1}

對於一個數 nn,將他分解質因數
n=i=1kpiaiφ(n)=φ(i=1kpiai)=i=1kpiaipiai1=i=1kpiai(11pi)=n×i=1k(11pi) n = \prod_{i=1}^k p_i^{a_i} \\ \varphi(n) = \varphi (\prod_{i=1}^k p_i^{a_i}) = \prod_{i=1}^k {p_i}^{a_i} - {p_i}^{a_i - 1} \\ = \prod_{i=1}^k {p_i}^{a_i} (1 - \frac{1}{p_i}) = n \times \prod_{i=1}^k (1 - \frac{1}{p_i})

以上爲歐拉函數的通式。

衆所周知,歐拉函數爲積性函數,有 φ(ab)=φ(a)φ(b)\varphi(ab) = \varphi(a)\varphi(b),其中 aabb 互質。所以可以用線性篩的方法在求質數表的同時求歐拉函數。需要用到以下性質,其中 pp 爲質數

  1. φ(p)=p1\varphi(p) = p - 1

  2. pip|i,那麼 φ(i×p)=φ(i)×p\varphi(i \times p) = \varphi(i) \times p,證明略。

  3. p∤  ip \not| \ \ i,那麼 φ(i×p)=φ(i)×(p1)\varphi(i \times p) = \varphi(i) \times (p-1)

略證:若 p∤  ip\not| \ \ i,那麼 iipp 互質,根據積性函數的性質 φ(i×p)=φ(i)×φ(p)=φ(i)×(p1)\varphi(i \times p) = \varphi(i) \times \varphi(p) = \varphi(i) \times (p - 1)

int pr[N + 5], vis[N + 5] = {1, 1}, phi[N + 5], n, tot;
void init() {
	for (int i = 1; i <= N; i++) {
		if (!vis[i]) {
			pr[++tot] = i;
			phi[i] = i - 1;
		}
		for (int j = 1; j <= tot && i * pr[j] <= N; j++) {
			vis[i * pr[j]] = 1;
			if (i % pr[j] == 0) {
				phi[i * pr[j]] = phi[i] * pr[j];
				break; 	
			}
			phi[i * pr[j]] = phi[i] * (pr[j] - 1);
		}
	}
} 

中國剩餘定理

中國剩餘定理給出了以下的同餘方程組,假設 m1mnm_1 \sim m_n 兩兩互質,求 xx 滿足
(S):{xa1(modm1)xa2(modm2)xan(modmn) (S): \begin{cases} x \equiv a_1 \pmod{m_1} \\ x \equiv a_2 \pmod{m_2} \\ \quad \vdots \\ x \equiv a_n \pmod{m_n} \end{cases}
中國剩餘定理構造如下

M=i=1nmiM = \prod_{i=1}^n m_iMi=MmiM_i = \frac{M}{m_i}tit_iMiM_i 在模 mim_i 意義下的乘法逆元,即爲 Mi×ti1(mod  mi)M_i \times t_i \equiv 1(\mod m_i)

方程 (S)(S) 的通解公式爲
x=kM+i=1naitiMi x = kM + \sum_{i=1}^n a_it_iM_i
如果 k=0k = 0,則 xx(S)(S) 的最小解。

略證:對於 aia_imim_i,有
tiMimodmi=1    aitiMimodmi=aimodmi t_iM_i \bmod m_i = 1 \iff a_it_iM_i \bmod m_i = a_i \bmod m_i
對於 aj,mj(ji)a_j, m_j \quad (j \not= i),有 miMim_i|M_i。所以 ajtjMjmodmi=0a_jt_jM_j \bmod m_i = 0

對於 kMkM,同理 kMmodmi=0kM \bmod m_i = 0

綜上所述,x=kM+i=1naitiMix = kM + \sum_{i=1}^n a_it_iM_i 爲方程 (S)(S) 的通解。k=0k = 0 時有最小解。

對於上述式子,tit_i 可以用 exgcd 求逆元的方法求。因爲 m1mnm_1 \sim m_n 兩兩互質 j=1nmj\prod_{j=1}^n m_j 在約去 mim_i 後爲 MiM_i 且與 mim_i 互質。

發佈了40 篇原創文章 · 獲贊 39 · 訪問量 1591
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章