數論

前言

數論剛掃過一次,雖然不是太全面(那就只能後邊再補起來了),爲了爲後邊的複習作準備,就來整理了一下。
這裏大致把內容分爲幾個板塊,方便一塊兒複習,要看刷的題,確定仍是隻能去
https://docs.qq.com/sheet/DTkVGZFpkQkhRS2N1?tab=25ta5r&c=D346A0LZ0算法

一.整除

定義

對於兩個正整數𝑝和𝑞,若存在正整數𝑥,知足𝑝𝑥 = 𝑞,則
稱𝑝整除𝑞 ,記做𝑝|𝑞。
整除的相關性質:
  1.自反性:𝑝|𝑝
  2.傳遞性:𝑝|𝑞, 𝑞|𝑟 → 𝑝|𝑟
  3.反對稱性:𝑝|𝑞, 𝑞|𝑝 → 𝑝 = 𝑞優化

帶餘除法

定義

對於正整數𝑎, 𝑏,存在惟一一對整數(𝑞, 𝑟),知足𝑎 = 𝑏𝑞 + 𝑟 且0 ≤ 𝑟 < 𝑏。稱𝑞爲商,𝑟爲餘數。spa

取整

下取整: \(\lfloor x \rfloor\) = max{𝑘 ∈ 𝑍|𝑘 ≤ 𝑥}
上取整: \(\lceil 𝑥 \rceil\) = min{𝑘 ∈ 𝑍|𝑘 ≥ 𝑥}
能夠發現𝑞 = \(\lfloor \frac{a}{b} \rfloor\)code

取模

對於正整數𝑎, 𝑏,定義模運算爲
𝑎 mod 𝑏 = 𝑎 − \(\lfloor \frac{a}{b} \rfloor\)⌋𝑏
注意在C++中,除法返回的結果是向0取整。遞歸

1.歐幾里得算法

固然,這個也就灰常簡單了,因此直接貼代碼。。。
inline LL GCD(LL A,LL B) { return !B ? A : GCD(B,A%B); }get

2.裴蜀定理

內容:

不定方程𝑎𝑥 + 𝑏𝑦 = 𝑐有解,當且僅當gcd (𝑥,𝑦) | c.class

證實&求解:

必要性顯然
充分性證實能夠考慮在求解gcd的時候遞歸構造解。擴展

\[ ax+by=c \]

\[ b'y+a'(x\:mod\: y)=c \]

\[a' \left( x- \lfloor \frac{x}{y} \rfloor y \right) +b'y= c \]

\[a'x+\left( b'-a' \lfloor \frac{x}{y} \rfloor \right) y = c \]

每一次令a = a',b = b'-a' \(\lfloor \frac{x}{y} \rfloor\)
邊界條件是當y = 0時,a = \(\frac{c}{x}\),b = 0。
(Of Course 裴蜀定理確定不可能就這!)
(因此能夠問一問數競大佬萌。。。(順便獻上個人膝蓋))
(QQ:849387128 630118646)gc

3.擴展歐幾里得算法(Ex_GCD)

主要思想就是先找到一組通解,在進行變化求出想要的類型的全部解。
求特解:im

inline LL Ex_GCD(LL A,LL B) {
	if(!B) { X=1; Y=0; return A; }
	LL Res=Ex_GCD(B,A%B);
	LL Temp=X; X=Y; Y=Temp-(A/B)*Y;
	return Res;
}

求出來以後的就是X0了。
對於以後的過程,通常會要求算出最小非零整數解。

inline bool MLE(LL a,LL b,LL n)
{
	LL x0;
	LL D=Ex_gcd(a,n);
	if(b%D) return false;
	x0=X*(b/D)%n;
	if(x0>0) Mans=min(Mans,x0);
	for(int i=1;i<=D;i++){
		if(((x0+i*(n/D))%n)>0) Mans=min(Mans,((x0+i*(n/D))%n));
	}
	return true;
}

4.質數

定義:

對於一個大於1的整數𝑥,若是它不被任何1 < 𝑦 < 𝑥的整數
𝑦整除,那麼稱𝑥爲質數或素數,不然稱𝑥爲合數。

定理

質數有無窮多個。

證實:

如有有限個質數𝑝1 \(\cdots\) 𝑝𝑚,則令𝑛 = \(\prod_{i = 1}^{m} pi\),則 𝑛 + 1 不能被𝑝1 \(\cdots\) 𝑝𝑚整除,因此 𝑛 + 1 也是質數。
\(\leq\) 𝑛的質數有𝜋(𝑛)個,則\(\pi \left( n \right) = O\left( \frac{n}{logn} \right)\)

算數基本定理

任何正整數都能惟一表示成一些質數的冪的乘積。

歐拉篩

(因爲本蒟蒻沒怎麼去了解其餘篩法,此處就先只寫一個最經常使用到的線性歐拉篩)
咱們想要獲得一個\(O \left( n \right)\)的算法。
在埃氏篩中,咱們發現了這樣一個問題:每個合數會被篩不少次,好比30這個數就被2,3,5各篩了一次。
能不能優化這個過程呢?換句話說,能不能使得每個合數都只被篩一次呢?
答案是確定的
咱們嘗試讓一個合數只在枚舉到它最小的質因子的時候被篩掉。
回顧埃氏篩的過程,當咱們到達𝑖時,咱們順次枚舉當前的全部質數,而且篩掉這個質數乘𝑖。由於咱們要讓這個質數是篩掉的合數的最小質因子,因此若是𝑖這個數包含𝑝這個質因子,那麼大於𝑝的全部質數就不用枚舉了,由於若是繼續枚舉獲得的數最小質因子都會小於當前枚舉的質數。
好比如今咱們有2,3,5這三個質數,如今i是6,那麼咱們枚舉到2的時候發現2是6的質因子,因此後面的3和5都不用枚舉了,由於 3 × 6,5 × 6 的最小質因子是2,而不是3和5。
(這個過程是照搬的,因此我沒有把排版弄太好。。。)

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

(先寫到這兒,下週再來寫,嘿嘿嘿QwQ

相關文章
相關標籤/搜索