數論知識


先言

本篇文章部分內容進行了相互穿插,請結合目錄食用 。 如有不便,望見諒。

模運算

顧名思義 , 在模意義下進行運算,滿足普通加法減法乘法運算 。
例如 \(a + b = c (mod \ \ p) => a\ \ mod \ \ p + b \ \ mod = c (mod \ \ p)\) 拿一個具體數字 , 即為
\(5 + 7 = 5 (mod \ \ 7) => 5 \ \mod \ \ 7 + 7 \ \ mod \ \ 7 = 5 + 0 = 5 (mod \ \ 7)\)
減法同樣如此,但是在減法進行計算的時候,有可能會變成負數,但我們盡量不想讓其變成負數,那我們可以轉化成這樣 $ ( (a - b )mod \ \ c + c )mod \ \ c$ 與 \((a - b) mod \ \ c\) 在模意義下是滿足相等的。

除法則是滿足不滿足的,只有當 \(p\) 為質數時, 才可以進行 。

快速冪

冪運算就是 \(a^b\) 這樣的運算 。快速冪就是將 \(a^b\) 轉化成 \((a ^{\frac{b}{2}} )^2\) ,從而達到快速計算,同時對 \(b\) 進行一下討論是否為奇數。
\(Code\) 模板

int quick_pow(int a , int b , int p) //a ^ b % p
{
	int ret = 1 ; 
	while(b) 
	{
		if(b & 1) ret = ret * a % p ; //指數為奇數 。
		a = a * a % p ; 
		b >>= 1 ;
	}
	return ret ; 
}

模板題 \(Code\)
略微推一下出來的模板題 \(Code\)

素數(質數)

定義就是只能夠被 \(1\) 或者他自身整除的數字 。

判定

\(1.\)判斷一下 $2 \to n - 1 $ 是否能為 \(n\) 的因子 ,復雜度 \(O(n)\)

n 一定能夠被分解成\(a \times b\) 我們假設 \(a < b\) 那么我們只需要枚舉 \(a\) 即可,因為如果 \(a\) 不滿足乘除 \(n\) ,那么也不會有其它數能乘除 \(n\) ,同時 可以顯然 \(a\) 的上界為 \(\sqrt n\)

\(2.\) 判斷一下 \(2 \to \sqrt n\) ,看一下能否為 \(n\) 的因子,復雜度 \(O(\sqrt n)\)

篩法

算術基本定理
\(x = \prod p_{i} ^ {c_i}\) \(p_i\) 是個質數 。對於任意的 \(x\in N\) 均滿足上述式子,也就是每個數,都能被分解成幾個質數和質數的平方的乘積 。
具體證明或者其他,詳見此博客

質數分布定理
\(1 \to n\) 的質數個數大約是: $ \frac{x}{\ln(x)}$ , 其數學中給出了詳細且嚴謹的證明,\(OI\) 就不必深究其證明了

\(1.\) 試除法篩素數 ,
原理:枚舉 \(1 \to n\) 這些所有的數, 同時,再用試除法 \(2\to \sqrt n\) 來判斷一下第 \(i\) 個數是否為素數 ,預計復雜度 \(O(n \times \sqrt n)\)

\(2.\) 埃氏篩
原理 : 就是由於素數的倍數必然不是一個質數,那么我們在枚舉到一個質數的時候,我們將它的所有倍數刪除掉,那么剩下的,就是質數了 , 復雜度 : \(O(n\times \log(\log n))\)

for(int i = 2 ; i <= n ; i++) 
{
    if(!vis[i]) 
    {
        prime[++tot] = i ; 
        for(int j = i ; j * i <= n ; j++) 
        {
            vis[i * j] = 1 ;
        }
    }
}

\(3.\) 線性篩
原理和埃氏篩一致,都是刪去素數的倍數從而使得剩下便是質數,那么它是埃氏篩的進一步優化。也就是讓所有的數都只被訪問一遍。
實現:讓所有的數都只被訪問一遍,也就是只被輸出一遍,那么我們讓它只能被它的最小質因子訪問。

    for(int i = 2 ; i <= n ; i++)
    {
        //不管 i 是否為質都要篩掉其它數字 
        //從小到大枚舉素數 
        for(int j = 0 ; j < tot ;j++  刪去  prime * i)
        {
            int  p = prime[j] ; 
            //篩掉 i * p
            //保證p是最小i*p素因子
            if(p == 是i的最小質因子) break ; 
        }
    }

實際代碼

for(int i=2;i<=n;i++)
	{
		if(!num[i])
		{
			a[cnt++]=i; //統計其中的素數
		}
		for(int j=0;j<cnt&&i*a[j]<=n;j++) 
		{
			num[i*a[j]]=1;//刪除其素數的倍數
			if(i%a[j]==0)//保證是最小質因子
			{
				break;
			}
		}
	}

模板題 \(Code\)

gcd , lcm

一些約定

我們規定\(gcd(x,y)\)表示的是\(x,y\)的最大公約數,同時\(lcm(x,y)\)規定為最小公倍數。

規定\(a|b\)表示\(a\)能夠乘除\(b\)
規定\(a \ \ mod \ \ b\)表示\(a\) %\(b\)

求解

\(1.\) 輾轉相除法(歐幾里得算法)
先來看一下其遞歸式

gcd(int a , int b) 
{
    return !b ? a : gcd(b , a % b) ; 
}

其復雜度是 \(O(log)\)

證明

證明 \(gcd(a , b) = gcd(b , a\text{%}b)\)
\(r = a \text{%}b , d = gcd(a , b),a = p1\times d , b = p2\times d\)
其中 \(p1,p2\) 互質(這個比較顯然吧,不互質的話還有公約數,那么就不是最大公約數了 ,那么我們就可以得到
\(r = a\text{%}b = a - k \times b = p1\times d - k\times p2 \times d = (p1 - k\times p2) \times d\) , 所以首先我們可以確定 \(r\) 一定是個 \(d\) 的倍數。

感性理解一下,由於我們搞出來的\(a \text{%} b\)是單調不增的,那么我們的值一旦找到,可不就是最大的。

又因為 \(b = p2 \times d\)
我們只需說明 \(p2 , p1 - k\times p2\) 互質即可說明 \(d\) 一定為最大公約數,
證明 \(p2 , p1 - k\times p2\) 互質:
假設 \(p2 . p1 - k\times p2\) 不互質。那么我們就有

\[p2 = m\times q , p1-k\times p2 = n\times q \]

\[p1 -k\times p2 = n\times q \]

\(p2 = m\times q\) 帶入可知

\[p1 - k\times m\times q = n\times q \]

\[p1 = k\times m\times q + n\times q = (k\times m+n)\times q \]

所以 \(a = p1\times d , b = p2\times d\)\(a = (k\times m + n)q \times d , b = m\times q \times d\)
\(a , b\) 的最大公約數為 \(q\times d\) , 則與假設不符,不成立,所以 \(p2 , p1-k\times p2\) 互質。所以 \(r\)\(b\) 的公約數也就是 \(d\)
所以 \(gcd(a, b) = gcd(b , a\text{%}b)\)

聯系

那么 \(lcm\)\(gcd\) 有什么關系呢?

\(x = gcd(a,b)\).
則顯然 \(x \mid a\),\(x\mid b\).
\(a_0 = [a\ / \ x]\ , \ b_0 = [b\ /\ x]\).
\(lcm(a_0 \ , \ b_0) = a_0 \times b_0\). \(gcd(a_0,b_0) = 1\)
\(lcm(a_0,b_0) \times gcd(a_0,b_0) \times x = a_0 \times b_0 \times x\)
又因為 ,最大公約數
所以 , \(lcm(a,b)= \frac {a \times b}{x}\)
也就是 \(lcm(a,b) \times x = a \times b\)
所以 , \(lcm(a,b) \times gcd(a,b) = a \times b\)
證畢,$over \ ~ \ $

模板題 \(Code\)

整除

【定義】: 如果\(x\) % \(y==0\) , 我們就說, \(y\)整除\(x\) ,記做(上方有約定,但是還是說一下) , \(y|x\) ,

【性質】 :(從數競同學那里嫖來的)
1.若\(b|a\) ,則\(b|(-a) , -b|a , (-b) |(-a) , |b| \ \ | \ \ |a|\) (最后面的是兩個絕對值)
2.滿足轉移性: 若\(a|b\) , \(b|c\) ,則\(a|c\)
3.若\(a,b,c\in Z\) ,且\(a|b , a|c\),則\(a|(b±c) , a| mb , a | mc , a | m(b±c)\),(\(mb\)代表\(m \times b\),沒有罵人的意思,也不是\(mb\)那一個變量的意思,不會吧,不會吧,還有人不知道嗎?)

我們可以將其進行一下推廣到一般情況:

\(a_i,b_i,c_i \in Z , i = 1 , 2 , 3 … n\),並且滿足\(a_i | b_i\),則有\(a|\sum\limits_{i=1}^{n} b_i \times c_i\),比較顯然吧。

4.設\(a,b\in Z\),且\(a|b\) ,則對於任意的\(m \in Z\) ,都滿足\(am | bm\) ,這是個充要條件。
5.若\(|a| < |b|\) , 且\(|b| \ \ | \ \ |a|\) ,則\(a = 0\)
6.若\(a,b\)互素,且\(p|\prod\limits_{i = 1}^{n} a_i\),則在\(a_1 ,a_2…a_n\)中,至少有一個\(a_i\),滿足\(p\ \ | \ \ a_i\)
7.若\(a,b\)互素,且\(a|b\times c\) ,則\(a|c\)
8.\(n\)個連續整數的乘積必然能被\(n!\)整除。
9.若\(p\)為素數,對任意的正整數\(n\),都滿足\(p | (n ^p - n)\).這性質叫做費馬小定理,證明在求解逆元時會予以證明。

逆元

求解逆元的方法

什么叫做逆元 , 我們認為 \(a \times a^{-1} = 1 (mod \ \ p)\) ,我們稱 \(a^{-1}\)\(a\)\(p\) 意義下的逆元

\(1.\) 遞推求解逆元

假設 \(p = k\times i + r| i > r\)

\[k\times i + r ≡ 0 (mod \ \ p) \]

對兩邊同時乘上 \(i^{-1} , r^{-1}\) 就得到

\[k\times r^{-1} + i^{-1} ≡ 0 (mod \ \ p) \]

然后就有了

\[i^{-1} ≡ - k \times r^{-1}(mod \ \ p) \]

同時,\(i > r\) ,這就形成了線性遞推關系

\[f_i = -p/i \times f_{p \ \ mod \ \ i} \]

// 求 1 -> n的逆元
inv[i] = 1 ; 
for(int i = 2 ; i <= n ; i++) 
{
    inv[i] = (-p/i + p ) * f[p % i] ;
}

\(2.\) 費馬小定理求解逆元。

證明費馬小定理的正確性:(事實證明,證不出來背過亦可)
占個坑 , 以后證完補。

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

然后就是一個快速冪的事,不必附代碼

\(3.\) 擴歐求求解逆元。

占個坑,等講完之后有了更深的理解再寫。

逆元的應用

可以進行模意義下除法,我們在模意義下是不能進行除法的,但是我們可以利用逆元將除法轉化成乘法,就行了。

為什么模意義下不能進行除法,因為會導致出現實數,而余數顯示不能為小數。

擴展歐幾里得算法

先證明出歐幾里得顯然在這里變得是比較重要。
鳴謝 : 歐幾里得算法與擴展歐幾里得算法_C++

引理

擴展歐幾里得是用來求解線性同余方程 ,逆元,不定方程的一種算法。
引理 : 對於任意的整數 \(a,b\) ,存在 \(x,y\) 使得 \(gcd(a,b) = a\times x + b\times y\)

證明

\(b = 0\) 時 , \(gcd(a,b) = a\) , 此時 , \(x = 1 , y = 0\)
\(b\not = 0\)

\[a\times x_1 + b\times y_1 = gcd(a ,b) = gcd(b , a\text{%}b) = b\times x_2 + a\text{%}b\times y_2 \]

\[\because a\text{%}b = a - [a/b]\times b \]

\[\therefore a\times x_1 + b\times y_1 = b\times x_2 + (a - [a/b] \times b) \times y_2 \]

\[\therefore a\times x_1 + b\times y_1 = a\times y_2 + b\times (x_2 - [a/b]\times y_2) \]

\[\therefore x_1 = y_2 ,y_1 = x_2 - [a/b] \times y_2 \]

\(b = 0\) 時會得到最后的一組解,其他的均可以又上述的推導出來。

代碼實現

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

沒有啥模板題讓着寫這玩意證明的。

exgcd 求解不定方程

【鳴謝】
對於一個 \(a\times x + b\times y = c\) 這一個不定方程, \(d = gcd(a,b)\) ,那么顯然的 , \(d|(a\times x + b\times y)\) , 所以,如果 \(c\text{%}d \not = 0\) , 那么就說明是無解的。如果有解的話 :
我們能夠推出一組特解。
很顯然,我們是有 \(a\times x_1+ b\times y_1 = d\) , 同樣的,我們設 \(q \times d = c\) , 將上述式子乘以 \(q\) , 則有

\[a \times x_1\times q + b\times y_1\times q = d\times q \]

\[\therefore x_0 = x_1 \times \frac{c}{d} , y_0 = y_1 \times \frac{c}{d} \]

這樣就得到一組特殊解,我們通過特殊解進行推導通解。

我們推導一般的式子,即為

\[a \times (x_0 + m) + b\times (y_0 + n) = c \]

\[a\times x_0 + a\times m + b\times y_0 + b\times n = c \]

那么我們讓 \(a\times m + b\times n = 0\) ,就可以滿足上述的式子了。
所以我們就有 \(a\times m = -b\times n\) , 同理可以得到 , \(m = t \times \frac{b}{a} , n = -t\times \frac{a}{b}\) , 其中 \(t\) 為任意取得。

【模板題】
\(Code\)

exgcd 求線性同余方程

關於一個模方程 \(a \times x \text{%} b = c\) 求解。
我們可以將其轉化成

\[a \times x - c = b\times y \]

同理, 就可以得到

\[a\times x - b\times y = c \]

然后發現這是一個不定方程,很雞賊,和上面一致即可。
【模板題】
\(Code\)
【青蛙的約會】
\(Code\)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM