---
type : slide
---
# 簡單數論
----
數學是程式中最重要的一部分
---
# gcd(最大公因數)
----
## 輾轉相除法(迴圈)
```cpp=
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
```
----
## 輾轉相除法(遞迴)
```cpp=
int gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a % b);
}
```
----
## 內建gcd函式
```cpp=
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int a = 10,b = 15;
cout<<__gcd(a,b)<<endl;
}
```
---
# lcm(最小公倍數)
----
## code
```cpp=
int lcm(int a, int b) {
return (a * b) / __gcd(a, b);
}
```
---
# 快速冪
----
## 作用:快速計算平方數
## 原理:分治法
----
```cpp=
int fastpow(int x, int n){
if(n == 0)
return 1;
int ans = fastpow(x, n/2);
if(n % 2 == 0)
return ans * ans;
return ans * ans * x;
}
```
時間複雜度:O(log n)
---
# 判斷質數
----
## 窮舉法-1
```cpp=
bool isprime(int n)
{
if (n <= 1) return false;
// 窮舉所有可能的因數
for (int d=2; d<n; ++d)
if (n % d == 0)
return false;
return true;
}
```
時間複雜度 O(n)
----
## 窮舉法-2
```cpp=
bool isprime(int n)
{
if (n <= 1) return false;
// 窮舉小於等於sqrt(n)的因數
for (int d=2; d*d<=n; ++d)
if (n % d == 0)
return false;
return true;
}
```
時間複雜度 O(sqrt(n))
----
## 6n±1 method
將數字分成 6n 、6n+1 、 6n+2 、 6n+3 、 6n+4 、 6+5,只需要拿 6n+1 和 6n+5 試除。
----
## 6n±1 method
```cpp=
bool isprime(int n) {
if (n <= 1) return false;
if (n == 2) return true;
if (n == 3) return true;
if (n % 2 == 0) return false;
if (n % 3 == 0) return false;
for (int d=5, gap=2; d*d<=n; d+=gap, gap=6-gap)
if (n % d == 0)
return false;
return true;
}
```
----
## Miller–Rabin primality test
結合 square root primality test 與 Fermat primality test 。
----
## 費馬小定理
**若n是質數,a小於n,則aⁿ ≡ a (mod n)。**
**若n是質數,a小於n,a不是零,則aⁿ⁻¹ ≡ 1 (mod n)。**
----
## 平方根測試法
**以質數n為模數,0到n-1之間,只有1與n-1,平方之後等於1。
以質數n為模數,1的平方根一定是1與n-1(即±1)。**
----
## Miller–Rabin primality test
```cpp=
bool miller_rabin(int n)
{
if (n < 2) return false;
// srand(time(0));
int a = rand() % (n-2) + 2;
int u = n-1, t = 0;
while (u % 2 == 0) u >>= 1, t++;
int x = pow(a, u, n); // x = a ^ u % n;
if (x == 1 || x == n-1) return true;
for (int i=0; i<t-1; i++)
{
x = mul(x, x, n); // x = x * x % n;
if (x == 1) return false;
if (x == n-1) return true;
}
return false;
}
```
---
資料來源:https://web.ntnu.edu.tw/~algo/Prime.html