數論 I

5th Nov. 2019

可能大家都覺得很簡單

那就再聽一次吧!

以資訊方法解決數論問題

Today

暖身

有 \( n \) 袋米編號依序為 \( 1 \) 到 \(n \) ,其中一袋裝著全部都是壞掉的米,另外 \( n - 1 \) 袋裝的都是正常的米。已知一粒正常的米重\( 1 \) 單位,而一粒爛掉的米重 \( 0.1 \) 單位。現在,你有一個電子秤(可以告訴你重量)但是只能秤一次,請問你要怎麼知道爛掉的米是哪一袋?假設一袋的米夠多可以一直拿而不會取盡。

暖身 —— 解答

從第 \( i \) 袋取 \( i \) 粒米

設爛掉的是第\( k \)袋,則重量 \( \left( \sum^n_{i = 1} i  \right) - 0.9k\)

可以直接算!

同餘

定義 —— 同餘

我們定義同餘 \( a \equiv b \pmod{m}  \)若且唯若\( a \) 取\( m \) 的餘數等於 \( b \) 取\( m \) 的餘數

Ex. \( 5 \equiv 7 \pmod 2\) 、\( 7122 \equiv 12 \pmod 9 \)

定義 —— 整除

我們定義整除 \( a \vert b   \)若且唯若存在一個整數\( k \) s.t. \( b = ak \)

Ex. \( 123 \vert 0 \) 、\( 1 \vert 12  \) 、\( -2 \vert 226  \) 皆為真

同餘的性質

  • 可以加:\( a \equiv b \pmod m \iff a  + c \equiv b + c \pmod m \)
  • 可以乘:\( a \equiv b \pmod m \implies ac \equiv bc \pmod m \)

不是都能除!

反例: \( 6 \equiv 12 \pmod 3 \) 但是\( 1 \not \equiv 2 \pmod 3 \)

取餘數:扣

a % b

就醬

UVa 10127 - Ones

給定一個數字 \( N \),定義 \(f(N) \) 為 「將\(1, 2, \dots, N\)寫在一起所成的數字。例:

\( f(4) = 1234 \),\( f(6) = 123456 \) 。

請問 \( f(N) \) 是否為 \( \text{suum} \) (\(3\)) 的倍數?

( \( N \leq 10^8 \) )

整除

\( \gcd \) 和 \( \text{lcm} \) 函數

來定義一下

就是小學遇過的最大公約數(\( \gcd \))和最小公倍數(\( \text{lcm} \))啦

算數基本定理

(Fundamental Theorem of Arithemetic)

定理:每一個大於\(1\)的正整數都有一個唯一的質因數分解

證明:

正式定義 \( \gcd \)、\( \text{lcm} \) 

令 \( n  = \prod^{\infty}_{i = 1} p_i^{\alpha_i} \),\( m  = \prod^{\infty}_{i = 1} p_i^{\beta_i} \)

則 \(\gcd(n, m) = \prod^{\infty}_{i = 1} p_i^{\min(\alpha_i, \beta_i)} \)

\(\text{lcm}(n, m) = \prod^{\infty}_{i = 1} p_i^{\max(\alpha_i, \beta_i)} \)

令 \( n  = \prod^{\infty}_{i = 1} p_i^{\alpha_i} \),\( m  = \prod^{\infty}_{i = 1} p_i^{\beta_i} \)

則 \(\gcd(n, m) = \prod^{\infty}_{i = 1} p_i^{\max(\alpha_i, \beta_i)} \)

\(\text{lcm}(n, m) = \prod^{\infty}_{i = 1} p_i^{\min(\alpha_i, \beta_i)} \)

故 \(\gcd(n, m) \times \text{lcm} (n, m) = \prod^{\infty}_{i = 1} p_i^{\max(\alpha_i, \beta_i) + \min(\alpha_i, \beta_i)} \\ = n \times m\)

 

計算 \( \gcd \) —— 輾轉相除

給定一組\( (a, b) \),我們想要找到最大的 \( d \) s.t. \( d \vert a \) 且 \( d \vert b \)。

計算 \( \gcd \) —— 輾轉相除

給定一組\( (a, b) \),我們想要找到最大的 \( d \) s.t. \( d \vert a \) 且 \( d \vert b \)。

若 \( d \) s.t. \( d \vert a \) 且 \( d \vert b \),則 \( d \vert (a - b) \)!(假設\(a \geq b\) )

計算 \( \gcd \) —— 輾轉相除

若 \( d \) s.t. \( d \vert a \) 且 \( d \vert b \),則 \( d \vert (a - b) \)!(假設\(a \geq b\) )

若其中一者為 \( 0 \),則答案就是另外一者!

計算 \( \gcd \) —— 輾轉相除

演算法:給定了 \( a \) 和 \( b\) ,不斷拿小的減大的,直到其中一者為 \( 0 \) 或變得比另外一者更小。

最差複雜度:若小的為 \( \text{qlig} \),則會跑另外一個數字(設為 \( N \) ) 次,複雜度 \( O(N) \)!

超爛...

要減就減到變小啊 = =

那到什麼時候才會變小?

取餘數!

若 \( a \geq b \),與其一直算 \( a - b \),不如直接 \( a \% b \) 比較快!

int gcd(int a, int b){
    while(b > 0){
        a %= b;
        swap(a, b);
    }
    return a;
}

遞迴寫法

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

UVa 412 - Pi

就是一直算\(\gcd\)

一直算\(\gcd\)

一直算\(\gcd\)

一直算\(\gcd\)

一直算\(\gcd\)

UVa 10622 - Perfect P-th Powers

給定一個小於\(\text{int}\)範圍且大於\(2\)的數字\(x\),請求一個最大的正整數\(p\)使得存在一個正整數\(b\)使得

$$x  = b^p$$

模下次方

計算 \( a^x \pmod m \)

最簡單的方法

inline int modexp(int a, int b, int m){
    int ans = 1;
    for(int i = 0; i < b; i++){
        ans = ans * a % m;
    }
    return ans;
}

計算 \(a^b \pmod m \) 需要 \( O(b) \)

超爛啊,可不可以壓啊?

分而治之

想要計算 \( a^x \),若知道\( t=  a^{ \lfloor \frac{x}{2} \rfloor } \),那:

  • 若 \(x\) 為奇數,則 \(a^x = t^2 \times a \)
  • 否則 \(a^x = t^2\) 

只會計算 \(a, a^2, a^4, \dots, a^{2^{\log x}} \),故複雜度變成 \(O(\log n) \)

 

長這樣(遞迴):

int modexp(int b, int e, int m){
    if(!b) return 0;
    if(!e) return 1;
    int res = modexp(b, e/2, m);
    res = res * res % m;
    if(e % 2) res = res * b % m;
    return res;
}

長這樣(迭代):

int modexp(int b, int e, int m){
    int res = 1, current = 1;
    for(int i = 0; (1LL << i) <= e; i++){
        if((1LL << i) & e){
            res = res * current % m;
        }
        current = current * current % m;
    }
}

矩陣冪

若有一個 \(n \times m\)的矩陣\(A\),和一個\(m \times k\)的矩陣\(B\),則他們的積會是一個\(n \times k\)的矩陣\(C\),元素定義如下:

$$C_{ij} = \sum^{k}_{t = 1} A_{it}B_{tj}$$

矩陣快速冪

對於一個\(n \times n\)的矩陣\(A\)和一個正整數\(x\),我想要求\(A^x\)。

快速冪!

\( O(n^3 \log x) \)

模下的線性方程

なに???

模數下的線性方程

\( ax + b \equiv 0 \pmod m\)

我們想要解這個:

模數下的線性方程

\( ax \equiv -b \pmod m\)

不能除怎麼辦?

Money 元

模逆元

對於一個數字 \( a \) 和一個模數 \( m \), \( a\) 的模逆元 \( a^{-1} \) 就是滿足

  • \( 0 < a^{-1} < m \)
  • \( a^{-1} \cdot a \equiv 1 \pmod m \)

的數字

不一定存在!條件: \( \gcd (a, m) = 1 \)

費馬小定理

給定一個質數 \( p \) 和一個小於 \(p\) 的數字 \(a \) ,恆有

 

\( a^{p - 1} \equiv 1 \pmod p \)

證明:

首先列出\( a, 2a, \dots, (p - 1)a \)共\( (p  - 1)\)個數字。

 

若 \( sa \equiv ra \pmod p \)則一定有 \( p | (s - r) a \), \(p | (s -r) \) 或 \( p | a \)。但這兩者都比 \( p\)小,所以 \(s - r = 0\),也就是那\(p - 1\)個數字為一個完全剩餘系。

證明:

將那些數字乘起來,則:

$$a \cdot 2a \cdot 3a \dots \cdot (p - 1)a \equiv 1 \cdot 2 \cdot 3 \dots \cdot (p - 1) \pmod p$$

$$(p - 1)! \cdot a^{p - 1} \equiv (p - 1)! \pmod p$$

 

\((p - 1)!\)與\(p\)互質,所以可以除

$$ a^{p - 1} \equiv 1 \pmod p $$

質數下的模逆元

由於費馬小定理,$$a^{p - 1} \equiv a \cdot a^{p - 2} \equiv 1 \pmod p $$

故計算 \( a^{p - 2} \) 就可以計算模逆元!

非質數的狀況

擴展歐幾里德!

(變強版輾轉相除)

貝祖定理:對於兩個\(a, b\),一定存在無限多組\(x, y \in \mathbb{Z} \) s.t. \(ax + by = \gcd(a, b) \)

證明:略。爽。

非質數的狀況

擴展歐幾里德!

(變強版輾轉相除)

假設 \( \gcd(a, m) = 1 \),我們想要找到一個 \(b\) s.t. \(ab \equiv 1 \pmod m\)

非質數的狀況

擴展歐幾里德!

(變強版輾轉相除)

$$ab \equiv 1 \pmod m$$

代表存在一個 \(k\) s.t.

$$ab - 1 = mk \implies ab - mk = 1$$

 

輸入 \((a, m)\),得到\(b, k\)即可!

遞迴看看

想要求\(ax + by = 1\)的解,若知\((x', y')\)滿足

$$bx' + (a - \lfloor \frac{a}{b} \rfloor b)y' = 1$$要怎麼得到解?

 

遞迴看看

想要求\(ax + by = 1\)的解,若知\((x', y')\)滿足

$$bx' + (a - \lfloor \frac{a}{b} \rfloor b)y' = 1$$要怎麼得到解?

 

祕技:等量公理

遞迴看看

 

$$bx' + (a - \lfloor \frac{a}{b} \rfloor b)y' = 1$$

$$ay' + b\left( x' - \lfloor \frac{a}{b} \rfloor y' \right)  = 1$$

 

實作

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

參數才會爽

補充:得到其他解

若已經知道 \(ax + by = \gcd(a, b)\),則對於任何一個\(k \in \mathbb{Z} \),\((x', y') = (x + bk, y - ak)\)也會是一組解

質數篇

Optimus Prime

優化質數?

求 \(N\) 以下的所有質數

大家都會\(O(N^2)\)吧...

Sieve of Ἐρατοσθένης

埃拉托斯特尼篩法

Sieve of Ἐρατοσθένης

埃拉托斯特尼篩法

演算法:一開始所有的數字都是質數。從\(2\)開始,將大於它其所有的倍數都標示為不是質數。

正確性:一個質數不會被比他前面的數字篩到,因為它不是任何一個比它小的數字的倍數!

Code

簡單明瞭

const int maxN = 1e5;
bool isPrime[maxN];
inline void sieve(){
    for(int i = 0; i < maxN; i++) isPrime[i] = true;
    isPrime[0] = isPrime[1] = false;
    for(int i = 2; i < maxN; i++){
        for(int j = 2 * i; j < maxN; j += i) 
            isPrime[j] = false;
    }
}

複雜度 + 優化

複雜度:時間為

\(\sum^{N}_{k = 1} \frac{N}{k}\),為 \(O(N \log N)\)

優化:

  1. 可以遇到質數再開始篩!

  2. \( j\) 不用從 \(2i\) 開始跑,可以從\(i^2\)!

複雜度 + 優化

  1. 可以遇到質數再開始篩!

  2. \( j\) 不用從 \(2i\) 開始跑,可以從\(i^2\)!

質數倒數和更小:

$$\sum_{p  \leq n} \frac{1}{p} = O(\log\log n)$$

故演算法為 \(O(N \log \log N)\)!

線。性。篩。

by Euler

邁向真線性

我們想要每一個合數都被篩掉一次

每一個合數\(N\)都有一個最小質因數\(p_{\min} \),我們想要在\(i = \frac{N}{p_{\min}}\)的時候篩掉

邁向真線性

若目前在\(i\),若\(i\)未被篩掉,則其為質數;也維護一個目前所篩過的質數與之比對。對於每一個質數\(p\):

  • 若\(p \times i > N \)直接跳出

  • 則\(p \times i \)不是質數,且\(p\)為\(ip\)的最小質因數

  • 若\(i\)為\(p\)的倍數,則跳出。

 

邁向真線性

若\(i\)為\(p\)的倍數,則跳出。

因為\(p\)就會是\(i\)的最小質因數了(依序枚舉質數呀,第一個遇到的就是最小),所以之後的數字都會被\(p\)篩掉,不用急!

複雜度 \( O(N) \)!!!

扣的

const int maxN = 1e5;
bool isPrime[maxN];
vector<int> primes;

inline void getPrime(){
    for(int i = 0; i < maxN; i++) isPrime[i] = true;
    for(int i = 2; i < maxN; i++){
        if(isPrime[i]) primes.push_back(i);
        for(int p : primes){
            if(i * p > maxN) break;
            isPrime[i * p] = false;
            if(!(i % p)) break;
        }
    }
}

TIOJ 1668 - 分組編隊

給定兩個數字\(l, r\),請求有幾個在\([l, r]\)的質數?(保證

\( 1 \leq l \leq r \leq 2^{31} - 1\)

 \(r - l \leq 2 \times 10^5 \)

中國剩餘定理

韓信點兵

《孫子算經》

下卷第二十六題 · 物不知數

「有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二。問物幾何?」

有一個數字 \(x \)

除\(3\)餘\(2\)

除\(5\)餘\(3\)

求 \(x\)?

除\(7\)餘\(2\)

$$ x \equiv 2 \pmod 3 $$

$$ x \equiv 3 \pmod 5 $$

$$ x \equiv 2 \pmod 7 $$

如果只有兩條式子會不會?

$$ x \equiv a_1 \pmod {m_1}$$

$$ x \equiv a_2 \pmod {m_2}$$

$$x = a_1 \cdot m_2 \cdot (m_2^{-1} \pmod{m_1}) + a_2 \cdot m_1 \cdot (m_1^{-1} \pmod{m_2})$$

構造解:

模\(m_1\)為\(1\)

模\(m_2\)為\(1\)

另外一邊會消掉!

最後再模\(m_1m_2\)就好

直接推廣一波

$$x \equiv a_i \pmod{m_i}$$

假設有\(n\)條式子,且所有的\(m_i\)皆互質,且滿足:

直接推廣一波

定義\(M_i = \prod_{k = 0, k \not= i}^{n} m_k\),

\(\mu_i = M_i^{-1} \pmod{m_i}\)

則可以知道:\(M_i\mu_i \) 在模 \(m_i\)之下為\(1\),在模其他的\(m_j\)之下為\(0\)。

直接推廣一波

則可以知道:\(M_i\mu_i \) 在模 \(m_i\)之下為\(1\),在模其他的\(m_j\)之下為\(0\)。

故構造:

$$x = \sum_{i = 1}^{n} M_i\mu_i a_i \pmod {\text{lcm}(m_i) }$$

或是用擴展歐幾里德

先看前兩條:

\(x \equiv a_1 \pmod {m_1}\)
\(x \equiv a_2 \pmod {m_2}\)

令\(x = m_1k_1 + a_1 = m_2k_2 + a_2\),則

$$m_1k_1 + a_1 = m_2k_2 + a_2$$

$$m_1k_1 - m_2k_2 = a_2 - a_1$$

或是用擴展歐幾里德

$$m_1k_1 + a_1 = m_2k_2 + a_2$$

$$m_1k_1 - m_2k_2 = a_2 - a_1$$

若\((a_2 - a_1) \not \vert \gcd(m_1, m_2)\)則無解

否則可以解得\(k_1\)的值,然後代回去,得到某種

$$x = A + K \times \text{lcm}(m_1, m_2)$$

變成一條式子:

$$x \equiv A \pmod{\text{lcm}(m_1, m_2)}$$

剩下\(n - 1\)條式子,可以繼續做下去!

方法比較

第一種方法:\(O(N)\),但是不能判斷有沒有解,數字可能會爆

 

第二種方法:\(O(N \log N)\),能判斷無解,數字不一定會爆但是比較能避免(因為是用\(\text{lcm}\))

ZeroJudge c637

滿滿的糖果屋 #3 

裸中國餘數定理

質因數分解

基本作法:

若想要分解\(N\),先建立\(\sqrt{N}\) 以下的所有質數,再一個一個篩。

對於一個數字\(N\),至多一個質因數是大於\(\sqrt{N}\)的。

Code

vector<pair<int, int> > factorize(int n){
    vector<pair<int, int> > vec;
    pii res;
    for(int p : primes){
        if(p * p > n) break;
        if(!(n % p)){
            res.F = p;
        	res.S = 0;
            while(!(n % p)){
                res.S++;
                n /= p;
            }
        }
    }
    if(n > 1) res.push_back({n, 1});
}

UVa 10235 - Simply Emirp

一個數字為「\(\text{Prime}\)」若其為質數;若其反過來寫也是質數,則其為「\(\text{Emirp}\)」。請判斷其為哪一個。

UVa 160 - Factors and Factorials

給定一個數字\(N\),請求\(N!\)的質因數分解為何?(\(N \leq 10^3\))

Copy of 數論 I

By ycsh1519

Copy of 數論 I

  • 169