1. 程式人生 > 實用技巧 >各大定理及證明(裴蜀定理,威爾遜定理,費馬定理,擴充套件歐幾里得,尤拉定理,擴充套件尤拉定理,中國剩餘定理,擴充套件中國剩餘定理)

各大定理及證明(裴蜀定理,威爾遜定理,費馬定理,擴充套件歐幾里得,尤拉定理,擴充套件尤拉定理,中國剩餘定理,擴充套件中國剩餘定理)

目錄

同餘,整除

整除的性質:

1.傳遞性:若\(a|b,b|c\),則\(a|c\)
2.\(a|b,a|c\)等價於對於任意的整數\(x,y\),有\(a|(bx+cy)\)
3.設\(m≠0\),則\(a|b\)等價於\(ma|mb\)
4.設整數\(x,y\)滿足\(ax+by=1,a|n,b|,n\),則\((ab)|n\)
5.若\(b=q*d+c\),則\(d|b\)的充要條件是\(d|c\)


同餘的性質:

1.同加性:若\(a\equiv b(mod\ p)\),則\(a+c\equiv b+c(mod\ p)\)
2.同減性:若\(a\equiv b(mod\ p)\),則\(a-c\equiv b-c(mod\ p)\)
3.同乘性:若\(a\equiv b(mod\ p)\),則\(a\times c\equiv b\times c(mod\ p)\)
4.同除性:若\(a\equiv b(mod\ p),c|a,c|b,(c,p)=1\),則\(a/c\equiv b/c(mod\ p)\)
5.同冪性:若\(a\equiv b(mod\ p),c>0\),則\(a^c\equiv b^c(mod\ p)\)


6.若\(a\% p=x,a\% q=x,(p,q)=1\),則\(a\% (p*q)=x\)


數論常識:

1.若2能整除a的最末位,則\(2|a\)
2.若4能整除a的末兩位,則\(4|a\)
3.若8能整除a的末三位,則\(8|a\)
4.若3能整除a的各位數字之和,則\(3|a\)
5.若9能整除a的各位數字之和,則\(9|a\)
6.若11能整除a的偶數位數字之和與奇數位數字之和的差,則\(11|a\)
7.能被\(7,11,13\)整除的數的特徵是:這個數的末三位與末三位以前的數字所組成數之差能被\(7,11,13\)整除


模運算

1.分配率

\((a+b)\% c=(a\% c+b\% c)\% c\)

\( \)(a-b)% c=(a% c-b% c)% c$$
\((a\times b)\% c=(a\% c\times b\% c)\% c\)\( \)(a^b)% c=(a% c)^b% c$$

2.放縮性

如果\(a\% b=c,d≠0\),則有\((a\times d)\%(b\times d)=c\times d\)
如果\(a\%b=c,d|a,d|b\),則\((a/d)\%(b/d)=(c/d)\)

根據放縮性,則除法取餘有式子↓
\(a/b\%c=a\%(b\times c)/b\)


埃式篩法

先把\(n\)以內的\(2\)的倍數(不包含\(2\))全部刪除,再把\(n\)以內的\(3\)的倍數(不包含\(3\))全部刪除,......,
這樣做下去,最後剩下的以內的數全為質數
這裡的刪除其實不是真的刪除,只是打上一個刪除標記而已
每個數都會被它的質因子打一次標記,而一個數的不同的質因子個數不超過\(logN\)
所以時間複雜度為\(O(NlogN)\)

void getprime( int n ) {
	for( int i = 2;i <= n;i ++ ) {
		if( flag[i] ) continue;
		prime[++ cnt] = i;
		for( int j = i;j <= n / i;j ++ )
			flag[j * i] = 1;
	}
}

尤拉篩法

在上述的埃氏篩法中,一個數可能被它的各個質因子都篩了一遍
而一個數的質因子種類數是不會超過\(logN\)的,所以時間複雜度為\(O(NlogN)\)
而歐式篩法保證每個數只被它的最小質因子篩一遍,這樣,時間複雜度便降成了\(O(N)\)


有一個質數集合\(S\),一開始,質數集合為空
同時有一個\(bool\)陣列\(flag\),表示刪除標記

有兩層迴圈:
外層迴圈從\(2\)開始列舉倍數,設當前列舉的量為\(a\)
如果\(a\)是質數,則將\(a\)加入質數集合
內層迴圈列舉質數集合中的元素,將陣列中它們的\(a\)倍全部打上刪除標記
顯然,未打刪除標記的數都是質數了(\(flag\)陣列中下標小於\(2\)的元素是無效的,不用考慮)

但現在的時間複雜度仍然是\(O(NlogN)\)的,接下來,要用一個優化來完成\(O(N)\)的蛻變

設當前倍數為\(a\),在內層迴圈中,設當前列舉到集合\(S\)中的第\(i\)個質數\(p_i\)
先將\(i*p_i\)打上標記
如發現\(i\)\(p_i\)的倍數時
此時後續的質數就無需再枚舉了,可以提前退出內層迴圈
外層迴圈處理下一輪,即\(a++\)


為什麼滿足這種條件就可以提前\(break\)呢?

設後續的質數為\(p_i'\),而\(p_i'>p_i\)
因為\(a\)\(p_i\)的倍數,那麼\(a\times p_i'\)也是\(p_i\)的倍數
\(a\times p_i'=b\times p_i\)
\(∵p_i'>p_i\)
\(∴b>a\)
我們希望每個數被它的最小質因子給刪掉
所以\(a\times p_i'\)應該被\(p_i\)刪掉(就要求\(a\times p_i'/p_i\)儘量大)
所以後續所有的質數就都留給倍數\(a\)增長到\(b\)再去處理了


void sieve( int n ) {
	for( int i = 2;i <= n;i ++ ) {
		if( ! flag[i] ) prime[++ cnt] = i;
		for( int j = 1;j <= cnt && i * prime[j] <= n;j ++ ) {
			flag[i * prime[j]] = 1;
			if( i % prime[j] == 0 ) break;
		}
	}
}

最大公約數和最小公倍數

\[gcd(a,b)\times lcm(a,b)=a*b \]

證明:
\(a,b\)進行質因子分解,設\(a,b\)的質因子集合並集為\(p_1,p_2,p_3...p_k\)

\[設a=p_1^{i_1}p_2^{i_2}...p_k^{i_k},(0≤i_1,0\le i_2...0\le i_k) \]

\[設b=p_1^{j_1}p_2^{j_2}...p_k^{j_k},(0\le j_1,0\le j_2...0\le j_k) \]

\[gcd(a,b)=p_1^{min(i_1,j_1)}p_2^{min(i_2,j_2)}...p_k^{min(i_k,j_k)} \]

\[lcm(a,b)=p_1^{max(i_1,j_1)}p_2^{max(i_2,j_2)}...p_k^{max(i_k,j_k)} \]

\[∵min(i_t,j_t)+max(i_t,j_t)=i_t+j_t \]

\[∴gcd(a,b)+lcm(a,b)=p_1^{i_1+j_1}p_2^{i_2+j_2}...p_k^{i_k+j_k} \]


輾轉相除法

\[gcd(a,b)\equiv gcd(b,a\%b) \]

證明:
\(d=gcd(a,b),a=x*d,b=y*d\)
根據模運算的放縮性有:\(a\%b=(x*d)\%(y*d)=(x\%y)*d\)
\(∵(x,y)=1\)
\(∴(y,x\%y)=1\)

int gcd( int x, int y ) {
	if( ! y ) return x;
	else return gcd( y, x % y );
}

更相減損術

若約分\(\frac{a}{b}\)
\(a,b\)均為偶,可先將\(a,b\)折半,即\(/2\)
否則,將\(a,b\)交替的減去對方
直到最後兩數相等,此時的數乘上先前除掉的\(2\)即為原來\(a,b\)的最大公約數


裴蜀定理

如果\(a,b\)的最大公約數為\(d\),且\(d|c\),則存在整數\(x,y\),使得\(ax+by=c\)

證明:
轉化證明存在\(x,y\)使得\(ax+by=d\)
假設存在這樣一對\(x,y\),那麼只需將其進行倍數放縮即可
\(∵(a,b)=d\)
\(∴\)\(a'=a/d,b'=b/d\)
則有\(a'x+b'y=1,(a',b')=1\)
證明轉化為 求一對\(x,y\),使得\(a'x+b'y=1\),且滿足\((a',b')=1\)
即求證\(a'x\%b'=1\)(感性理解:若干倍的\(a'\)減去若干倍的\(b'\)等於\(1\)


引理一

如果\(a,b\)為正整數,且\(a,b\)互質,則不存在小於\(b\)的正整數\(k\),使得\(0\equiv k*a(mod\ b)\)

證明:
用反證法即可,假設存在這樣的一個\(k\)使得該式成立
則需滿足\(k\)或者\(a\)能整除\(b\)
\(∵(a,b)=1\)
\(∴a\)不可能整除\(b\)
\(∵0<k<b\)
\(∴k\)亦不可能整除\(b\)


推論

如果\(a,b\)為正整數,且\(a,b\)互質,則\(0,a,a*2,a*3...(b-1)*a\)這些數取模\(b\),餘數互不相等

證明:
反證法
設存在\(0<i<j<b\),使得\(a*i\equiv a*j(mod\ b)\)
則有\((i-j)*a\equiv 0(mod\ b)\)
同理引理一,\(i-j,a\)都不可能整除\(b\),故與假設矛盾,不成立


引理二

如果\((a,b)=1\),則必存在一個整數\(k\),滿足\(k*a\% b=1\)

證明:

根據上面推論易知,這些數取模\(b\)的值只會在區間\([0,b-1]\)\(k=0\)時取模餘數為\(0\)
而且各不相同,其中一定存在取模後的餘數為\(1\)的值


根據引理二可知, 如果\((a,b)=1\),則必存在一個整數\(k\),滿足\(k*a\% b=1\)
\(k*a-p*b=1\),裴蜀定理得證


威爾遜定理

\((p-1)!\equiv -1(mod\ p)\)當且僅當\(p\)為質數

證明:

先證充分性——>\(p\)為質數,有\((p-1)!\equiv p-1(mod\ p)\)
假設\(0<i<p\),根據上面的裴蜀定理,可得\((i,p)=1\),且必存在一個整數\(j(0<j<p)\)
使得\(i\times j\%p=1\),即\(j\)\(i\)的逆元,由此可見逆元具有唯一性,相互性
所以在\([1,p-1]\)中逆元是一對一對的
然而……
也有可能存在\(i\)的逆元是本身的,那麼此時的\(i\)就要滿足以下條件
\(i^2\%p=1 \ \ \ ——>(i+1)(i-1)\%p=0\)
\(∴i+1=0\)\(p\)\(i-1=0\)\(p\)
\(∵0<i<p\)
\(∴i+1=p,i-1=0\)
\(i=p-1,1\)
每一對逆元取模\(p\)都為\(1\),需要證明的原式變成\(1*p-1\equiv p-1(mod\ p)\)
顯然成立,證畢


再證必要性——>\((p-1)!\equiv p-1(mod\ p)\),當該式成立時,\(p\)一定為質數
反證法,即證明\(p\)不為質數時,該式不成立
\(p\)不為質數,則\([2,p-1]\)中一定有\(p\)的因子,設為\(i\),則\(i,p/i\)均為\(p\)的因子
1.若\(i≠p/i\),則\(1\times 2\times 3\times ...\times (p-1)\)一定是\(p\)的倍數,取模\(p\)\(0\)
2.若\(i=p/i\),則\(1\times 2\times 3\times ...\times (p-1)\)一定是\(i\)的倍數,模\(p\)必為\(i\)的倍數
又因為\(p\)\(i\)的倍數,且\(i>1\),所以\(p-1\)不可能是\(i\)的倍數,所以\((p-1)!\equiv-1(mod\ p)\)


費馬定理

如果\(p\)為質數,且\(a\%p≠0\),則有\(a^{p-1}\%p=1\)

證明:

\[(a*1)* (a* 2)* ...*(a* (p-1))=a^{p-1}*(p-1)!\ \ (mod\ p) \]

\[∵(a,p)=1 \]

\[∴\{(a* 1)\% p,(a*2)\% p,...,(a*(p-1))\%p\}=\{1,p-1\} \]

即取模後的值互不相等,且\(∈[1,p-1]\)

\[∴(a*1)\% p,(a*2)\% p,...,(a*(p-1))\%p=(p-1)!\ \ (mod\ p) \]

\[(p-1)!=a^{p-1}(p-1)!\ \ (mod\ p) \]

\[∴a^{p-1}=1\ \ (mod\ p) \]

同餘等價類、剩餘系、縮系

對於一個正整數\(p\),所有非負整數模\(p\)的結果,只有\(p\)種可能,即\(\{0,1,2,...,p-1\}\)
\(p\)剩餘系指的是\(\{0,1,2,...,p-1\}\),即小於\(p\)的所有非負整數,這個集合中包含了所有模\(p\)的餘數
\(p\)的剩餘系記為\(Z_p\)
剩餘系中,每一個元素代表的是一類數
比如在剩餘系\(Z_p\)中,\(0\)表示的是所有模\(p\)\(0\)的數,即\(\{0,p,2p,3p...\}\)
\(1\)表示的是所有模\(p\)\(1\)的數,即\(\{1,p+1,2p+1,3p+1...\}\)
這些模\(p\)餘數相同的數,稱為同餘等價類
可以發現,在模意義下,所有的非負整數可以被分為若干同餘等價類
如果我們只考慮剩餘系中與模數p互質的數,便得到一個子集,稱為模p的縮系,記為\(Z_p^*\)
如p為6,則\(Z_p^*=\{1,5\}\)
縮系又稱為簡化剩餘系

尤拉函式

尤拉函式即為縮系的大小

\(\phi(1)=1\)
1.如果\(n\)為質數,則$$\phi(n)=n-1$$
2.如果\(n=a^p\),且\(a\)為質數,則$$\phi(n)=a^p-a^{p-1}=a^p(1-\frac{1}{a})$$
3.令\(n=a_1^{p_1}a_2^{p_2}...a_k^{p_k}\),根據積性函式性質

\[\phi(n)=\phi(a_1^{p_1})\phi(a_2^{p_2})...\phi(a_k^{p_k}) \]

\[=a_1^{p_1}(1-\frac{1}{a_1})*a_2^{p_2}(1-\frac{1}{a_2})...a_k^{p_k}(1-\frac{1}{a_k}) \]

\[=n*(1-\frac{1}{a_1})*(1-\frac{1}{a_2})*...*(1-\frac{1}{a_k}) \]

//求單個phi(n)
int getphi( int x ) {
	int ans = x;
	for( int i = 2;i * i <= x;i ++ ) {
		if( x % i == 0 ) {
			ans = ans / i * ( i - 1 );
			while( x % i == 0 ) x /= i;
		}
	}
	if( x > 1 ) ans = ans / x * ( x - 1 );
	return ans;
}
//求多個phi(n)
void getphi( int n ) {
	for( int i = 2;i <= n;i ++ ) {
		if( ! phi[i] ) {
			phi[i] = i - 1;
			for( int j = i << 1;j <= n;j += i ) {
				if( ! phi[j] ) phi[j] = j;
				phi[j] = phi[j] / i * ( i - 1 );
			}
		}
	}
}

尤拉定理

如果\((a,p)=1\),則\(a^{\phi(p)}\equiv1(mod\ p)\)

證明:
\(p\)的簡化剩餘係為\(\{p_1,p_2,p_3,...,p_k\}\)
\(∵(a,p)=1\)
\(∴\{a*p_1,a*p_2,...,a*p_k\}\)也構成了\(p\)的簡化剩餘系
(證明可參考裴蜀定理中的推論反證法
\(∴(a*p_1)*(a*p_2)*...*(a*p_k)\equiv p_1*p_2*...*p_k(mod\ p)\)
\(∴a^{\phi(p)}\equiv 1(mod\ p)\)


擴充套件尤拉定理

\(a,m\)為正整數,當\(r>\phi(m)\)時,有\(a^r\equiv a^{r\%\phi(m)+\phi(m)}\)

證明:
分類討論
1.如果\((a,m)=1\),則顯然成立
因為由尤拉定理得\(a^{\phi(m)}\equiv1(mod\ m)\)
2.若\((a,m)>1\)


引理一:

如果滿足
\(\begin{cases}x\equiv y\ (mod\ m)\\x\equiv y\ (mod\ n)\end{cases}\)
則有
\(x\equiv y\ (mod\ \ lcm(n,m))\)

證明:
顯然\((x-y)\)既是\(m\)的倍數,又是\(n\)的倍數,則其必然為\(lcm(n,m)\)的倍數


引理二:

如果\(p\)為質數,\(\phi(p^q)>=q\)

證明:
給兩種證明方法
法一:
以每\(p\)個為一個週期劃分
顯然\((p,p-1)=1,(p^2,p^2-1)=1,...,(p^q,p^q-1)=1\)
此時光考慮一部分就已經滿足\(\phi(p^q)=q\),故引理顯然成立


法二:
\(\phi(p^q)=p^{q-1}*(p-1)\)
根據數學歸納法
考慮\(q=1,\phi(p)>=1\)顯然成立
\(q=k\)時成立,即\(p^{k-1}*(p-1)>=k\)
\(∵k>1\)
\(∴\)顯然\(p^k*(p-1)>=k+1\)
即當\(q=k+1\)時,也成立


接下來繼續證明擴充套件尤拉定理
①若\(m=p^k\),即\(m\)為質數的冪時
\(∵(a,m)>1\)
\(∴p|a\)
由引理二可得\(\phi(p^k)\ge k\),即\(\phi(m)\ge k\)
\(∴r> \phi(m)\ge k\)
\(∴a^r=x*p^r=y*p^{\phi(m)}=z*p^k\)
\(m|a^r,m|p^{\phi(m)}\)
\(∴a^r\equiv a^{r\%\phi(m)+\phi(m)}\equiv 0(mod\ \ m)\)

②若\(m=p_1^{k_1}p_2^{k_2}...p_{n}^{k_n}\)
\(m_1=p_1^{k_1}\),則\(a^r\equiv a^{r\%\phi(m_1)+\phi(m_1)}\ \ (mod\ \ m_1)\)
\(m_2=p_2^{k_2}\),則\(a^r\equiv a^{r\%\phi(m_2)+\phi(m_2)}\ \ (mod\ \ m_2)\)
\(......\)
\(m_n=p_n^{k_n}\),則\(a^r\equiv a^{r\%\phi(m_n)+\phi(m_n)}\ \ (mod\ \ m_n)\)

咕咕咕咕。。。。(目前蒟蒻還證不出來,先把老師寫的放著,待填)

因為\(\phi(m)=\phi(m_1)*\phi(m_2)*...*\phi(m_n)\),又根據引理一,則得到:
\(a^r\equiv a^{r\%\phi(m)+\phi(m)}(\mod m)\)

區間逆元

如果整數\(a,b\)滿足\(a*b\%p=1\),則稱\(a,b\)在模\(p\)的意義下互為逆元
只有\((a,p)=1\),在模\(p\)的意義下\(a\)才有逆元,\(a\)的逆元記作\(a^{-1}\)

證明:
\((a,p)>1\),則令\(d=gcd(a,p),d|a,d|p\)
\(∴d|a\%p\)(感性理解為:x倍\(d\)減去y倍\(p\)直到\(x<y\),其差一定也為\(d\)的倍數)
\(∴a\equiv (x\%y)d\ (mod\ \ p)\)
\(∵d>1\)
\(∴(x\%y)d≠1\)

逆元的性質:若\((b,p)=1\),則\(a/b\%p=a*b^{-1}\%p\)

有一種求區間逆元的方式,時間複雜度為\(O(n)\)
設模數為\(m,f[n]\)表示\(n\)的逆元,其中\([1,n)\)的逆元已經求出,則
\(f[n]=(-f[m\%n]*(m/n)\%m+m)\%m\)

證明:


公式一:

\(f[i]=-f[m-i]\)

證明:
\(f[i]*i\equiv1\ \ \ (mod\ m)\)
\(f[i]*(m-i)\equiv-1\ \ \ (mod\ m)\)
\(f[m-i]*(m-i)\equiv1\ \ \ (mod\ m)\)
\(f[i]=-f[m-i]\)


公式二:

\(f[i]=k*f[k*i]\)

證明:
\(f[i*k]*(i*k)\equiv 1\ \ \ (mod\ m)\)
\((f[i*k]*k)*i\equiv 1\ \ \ (mod\ m)\)
\(f[i]*i\equiv 1\ \ \ (mod\ m)\)
\(f[i*k]*k=f[i]\)



\(f[n]=k*f[k*n]=m/n\times f[m-m\%n]\)
\(f[m-m\%n]=-f[m\%n]\)
\(f[n]=m/n\times (-f[m\% n])\)


擴充套件歐幾里得

擴充套件歐幾里得是用來求不定方程:\(ax+by=c\),且已知整數\(a,b,c\)
要求\(gcd(a,b)|c\),才能保證有解

演算法思想:遞迴求解
先求方程\(ax+by=gcd(a,b)\),求出該方程的解,乘上係數\(c/gcd(a,b)\)即為原方程的解

\[ax+by=gcd(a,b)=gcd(b,a\%b)=bx'+(a\%b)y'=bx'+(a-a/b*b)y' \]

\(a,b\)看做變數,移項合併同類項

\[ax+by=bx'+(a-a/b*b)y' \]

\[ax+by-bx'-ay'+a/b*by'=0 \]

\[xa-y'a+yb-x'b+a/b*y'b=0 \]

\[(x-y')a+(y-x'+a/b*y')b=0 \]

\[∵a*b≠0 \]

\[∴x-y'=0,y-x'+a/b*y'=0 \]

\[∴\begin{cases}x=y'\\y=x'-y'*(a/b)\end{cases} \]

只需要求出\(x',y'\)就可以求出\(x,y\)
而求\(x',y'\)可以繼續遞迴下去
\(gcd(a,b)\)中的引數\(b\)最終會變為\(0\),此時\(gcd(a,0)=a\)
於是有\(ax+by=gcd(a,0)=a\),可以求出\(x=1,y=0\)
這是最底層的\(x,y\),然後一層層返回,就可以求出最原始的\(x,y\)


注意,\(exgcd\)求出來的\(x,y\)滿足的方程組是\(ax+bx=gcd(a,b)\)
將這一對\(x,y\)乘上\(\frac{c}{gcd(a,b)}\),才是原方程的一組解

而且,這一組解只是一組特解,並不一定是最小的,可以通過通解公式去找到最小解\(x\)

\[ax+by=c \]

\[a(x-k)+b(y+\frac{ak}{b})=c \]

因為\(a\)縮小若干倍,為了保證方程的正確性,\(b\)就應該放大若干倍,所以需滿足\(b|ak\)

\[∴\frac{b}{gcd(a,b)}|\frac{a}{gcd(a,b)}k \]

\[∵(\frac{b}{gcd(a,b)},\frac{a}{gcd(a,b)})=1 \]

\[∴\frac{b}{gcd(a,b)}|k \]

所以原方程的\(a\)可以無限縮小\(\frac{b}{gcd(a,b)}\)倍,直到\(a<\frac{b}{gcd(a,b)}\)

void exgcd( int a, int b, int &d, int &x, int &y ) {
	if( ! b ) d = a, x = 1, y = 0;
	else {
		exgcd( b, a % b, d, y, x );
		y -= x * ( a / b );
	}
}
//求x的最小解
x = ( x * ( c / d ) % ( b / d ) + ( b / d ) ) % ( b / d )

中國剩餘定理

求一個模線性方程組\(x\)
\(\begin{cases}x\equiv a_1\ \ (mod\ \ r_1)\\x\equiv a_2\ \ (mod\ \ r_2)\\...\\x\equiv a_k\ \ (mod\ \ r_k)\end{cases}\)
其中\(r_1,r_2,...,r_k\)互質

對於\(r_i\),設\(A_i=\prod_{j≠i}r_j\)
\(∵(r_1,r_2,...,r_k)=1\)
\(∴(A_i,r_i)=1\)
則一定存在一個整數\(c_i\)滿足\(c_i*A_i\% r_i=1\)

\(x_i=a_i*c_i*A_i\),則\(x_i\%r_i=a_i\)
因為\(A_i\)是除了\(r_i\)以外的其他\(r\)值的最小公倍數
所以,\(x_i\%r_j=0(j≠i)\),即\(x_i\)模其他的\(r\)餘數都為\(0\),只有模\(r_i\)的時候,餘數為\(a_i\)

換言之,把\(x_i\)加到滿足其他方程\(j(j≠i)\)的解\(x_j\)上,\((x_i+x_j)\)也一樣滿足方程\(j\)
同理,如果\(x_j\)也是這麼求出來的,則\((x_i+x_j)\)也滿足方程\(i\)

那麼,我們對於每一個方程,都按照這個方法求出來該方程的解
把這些解累加起來,發現,這個和仍然滿足每一個方程
\(x=\sum_{i=1}^ka_i*c_i*A_i\%r_i\)

對於\(x\),加上所有的\(r\)值的最小公倍數,它仍然滿足所有方程
所以,只要存在\(x\),則意味著有無窮多組解

通解為:$$x=\sum_{i=1}^k(r_ic_iA_i%a_i)+p*\prod_{i=1}^kr_i,p∈Z$$


擴充套件中國剩餘定理

求一個模線性方程組\(x\)
\(\begin{cases}x\equiv a_1\ \ (mod\ \ r_1)\\x\equiv a_2\ \ (mod\ \ r_2)\\...\\x\equiv a_k\ \ (mod\ \ r_k)\end{cases}\)
其中\(r_1,r_2,...,r_k\)不一定互質

首先,取前兩個方程$$x=kr_1+a_1=pr_2+a_2$$$$kr_1-pr_2=a_2-a_1$$
這種形如\(ax+by=c\)的不定方程,可以用擴充套件歐幾里得計算
\(gcd(r_1,r_2)\)不能整除\(a_2-a_1\)時,方程組無解
否則,根據\(exgcd\),求出\(k_0\),滿足\(k_0*r_1-p*r_2=a_2-a_1\)
\(k\)的通解為:

\[k=k_0+b*(r_2/gcd(r_1,r_2)) \]

帶入到方程組\(x=k*r_1+a_1\)中,則有$$x=(k_0+b(r_2/gcd(r_1,r_2)))r_1+a_1=k_0r_1+blcm(r_1,r_2)+a_1,b∈Z$$
即$$x\equiv a_1\ \ (mod\ \ lcm(r_1,r_2))$$
這個方程相當於合併了原來的兩個方程,而形式上又和原來的方程一致
繼續採用這個方法,不斷地合併方程組中的兩個方程
直到最後合併為一個方程,則可以得到\(x\)的通解

注意在這個過程中,要注意求出的\(k_0\)\(k*r_1-p*r_2=(a_2-a_1)\)的解
而不是\(k*r_1-p*r_2=gcd(r_1,r_2)\)的解,前者是後者的倍數

//擴充套件中國剩餘定理,求最小整數解x的模板程式碼
#include <cstdio>
#define MAXK 10000005
#define int long long
int mod[MAXK], r[MAXK];

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

int Fabs( int x ) {
	return ( x < 0 ) ? -x : x;
}

signed main() {
	int m;
	while( ~ scanf( "%lld", &m ) ) {
		for( int i = 1;i <= m;i ++ )
			scanf( "%lld %lld", &mod[i], &r[i] );
		int noans = 0, d, x, y;
		for( int i = 1;i < m;i ++ ) {
			exgcd( mod[i], mod[i + 1], d, x, y );
			if( Fabs( r[i + 1] - r[i] ) % d ) {
				noans = 1;
				break;
			}
			x = ( x * ( ( r[i + 1] - r[i] ) / d ) % ( mod[i + 1] / d ) + ( mod[i + 1] / d ) ) % ( mod[i + 1] / d );
			int lcm = mod[i] / d * mod[i + 1];
			mod[i + 1] = lcm, r[i + 1] = ( x * mod[i] + r[i] ) % lcm;
		}
		if( noans ) printf( "-1\n" );
		else printf( "%lld\n", r[m] );
//r[m]可能等於0,所以根據題目要求,若要最小正整數,則為mod[m]
	}
	return 0;
}

終於寫完了!!!!!!!!!!!!!!!!!!!!!