repkironca
I was born again because of love, but died of the same reason.
Lecturer:\(y = tan(\theta) x - \frac{g\;x^2}{2\;{v_0}^2\;sin^2(\theta)}\)
理論上現在是第六堂
運算思維之雜七雜八
運算思維之數據分析
運算思維之三角函數
運算思維之排列組合
運算思維之向量、矩陣
聽起來很唬爛
實際上也很唬爛
乍聽之下很簡單,但看到題目不會寫
競程的一大能力,對不起我沒有
運算思維的倒數第二個主題
location:建中數學讀書會,你學會了嗎
result:這裡什麼鬼都沒有
ㄟ北一的數學競賽暑訓
有留上課存檔耶
ㄟ這裡有交大競程社
可以讓我蹭耶
整除
\(b\;|\;a\)
整除
\(b\;|\;a\)
\(e.g.\)
\(2\;|\;8,(-2)\;|\;8,2\;|\;(-8)\)
整除
已知 \(b\;|\;a\),\(c\;|\;b\),則 \(c\;|\;a\)
\(e.g.\)
\(4\;|\;8,2\;|\;4,由上得\;2\;|\;8\)
\(b\;|\;a,a = b \; q_1\)
\(c\;|\;b,b = c \; q_2\)
\(a=(c\;q_2)\;q_1\),c | a
整除
已知 \(b\;|\;a\),\(let\;m\in\mathbb{Z},b\;|\;ma\)
\(e.g.\)
\(2\;|\;8,2\;|\;16,2\;|\;24\)
整除
令有 \(a_1、a_2、...、a_n\)
\(m_1、m_2、...、m_n\) 等整數
且 b | \(a_1\)、b | \(a_2\)、...、b | \(a_n\)
則 b | \(\Sigma_{i = 1}^n(a_i\,m_i)\)
\(a_1=b\,q_1\)
\(a_2=b\,q_2\)
\(m_1\,a_1=b\,q_1\)
\(m_2\,a_2=b\,q_2\)
\(m_1\,a_1+m_2\,a_2\;=\;b\;(q_1\,+\,q_2)\)
\(b\;|\;m_1\,a_1+m_2\,a_2\)
\(e.g.\)
\(2\;|\;4,2\;|\;10\)
\(2\;|\;4×3 + 10×4 = 52\)
整除
已知 \(\frac{2n^3+n^2+13}{n+5}\;\in\;\mathbb{Z}\),求滿足條件的最大整數 n?
根據公式可推得 \(n+5\;|\;s(n+5) + b(n+5)\)
\((2n^3+n^2+13)÷(n+5)=(2n^2+9n-45)\;...\;212\)
\(Ans:207\)
公因數與公倍數
則稱 b 是 \(a_1、a_2、...、a_n\) 的 公因數,常以 () 表示
則稱 b 是 \(a_1、a_2、...、a_n\) 的 公倍數,常以 [] 表示
公因數與公倍數
因為阿蘇很懶所以他不想證明的性質們
排列不影響 ()、[] 的結果
[a, b, c] = [b, a, c] = [c, a, b] ...
[a, b, c] = [|b|, |a|, |c|]
別忘了負因數與正因數同時出現
R 他們就互質,不然呢
公因數與公倍數
因為阿蘇很懶所以他不想證明的性質們
這個等等會用到ㄛ
畢竟原班人馬還在那邊
跑不掉了
下個性質我必須附證明:(
公因數與公倍數
跑不掉了
下個性質我必須附證明:(
\(a、b \in \mathbb{Z},gcd(a, b) \, lcm(a, b) = a \, b\)
公因數與公倍數
\(x、y \in \mathbb{Z},gcd(x, y) = s,lcm(x, y)=t\)
\(xy - 3t - 5s + 8 = 0,求 x、y\)
s - 3 | t - 5 | s | t |
---|---|---|---|
1 | 7 | 4 | 12 |
7 | 1 | 10 | 6 |
-1 | -7 | 2 | -2 |
-7 | -1 | -4 | 4 |
X
X
X
gcd = 4,lcm = 12
\(Ans:(x, y) = (4, 12)\)
歐幾里得算法
短除法
歐幾里得算法
短除法
求 gcd(78, 60)?
\(ans:2×3=6\)
歐幾里得算法
短除法
求 gcd(78, 60)?
\(ans:2×3=6\)
從 2 往上數會天荒地老
通常都直接放棄
你知道自己最後要把多少數字乘起來
才能得到答案嗎 XD
短除法
歐幾里得算法
\(gcd(m, n) = gcd(n, r)\)
\(e.g.\)
\(32 = 6×5 + 2\)
\(gcd(32, 6) = 2 = gcd(6, 2)\)
\(m = nq + r\)
基本概念
歐幾里得算法
\(gcd(m, n) = gcd(n, r)\)
\(m = nq + r\)
基本概念
Why?
\(d\) 的倍數
而且比較大
\(d\) 的倍數
而且比較小
\(gcd(m, n) = gcd(n, r)\)
\(m = nq + r\)
基本概念
gcd(3869, 6497)
\(6497 = 3869×1 + 2628\)
\(3869 = 2628×1 + 1241\)
\(2628 = 1241×2 + 146\)
\(1241= 146×8 + 73\)
\(146= 73×2 + 0\)
歐幾里得算法
歐幾里得算法
把它用 code 實作出來呢
int gcd (int a, int b){
if (a < b) return gcd(b, a);
/*確保 a 絕對比較大*/
if (b == 0) return a;
/*到底了,a 是最大公因數*/
return gcd(b, a%b);
/*即 m = nq + r 的 n 與 r*/
}
聽起來就很遞迴對吧
歐幾里得算法
O( \(log N\) )
質數
e.g.
18 = 2 × 3 × 3
42 = 2 × 3 × 7
質數
e.g.
18 = 2 × 3 × 3
42 = 2 × 3 × 7
標準分解式
e.g.
\(1224=2^3 × 3^2 × 17\)
e.g.
18 = 2 × 3 × 3
42 = 2 × 3 × 7
質數
證明嗎,不然我們來假設質數是有限ㄉ
這坨質數為 \(p_1、p_2、...、p_n\),其乘積稱為 \(T_1\)
假設存在一自然數 \(T_2 =\Pi_{i=1}^N(p_i)+1\)
每個正合數都有唯一的質因數分解
\(T_2\) 不能被任何一個 \(p_i\) 整除,所以 \(T_2\) 是質數
但 \(T_2 > T_1\) 耶,說好的最大質數是 \(p_n\) 呢
整坨都矛盾,反證法做完ㄌ
質數
尋找質數的方法
窮舉啦哪次不窮舉
嗯哼,然後呢,你要怎麼判斷窮舉出的數字 \(N\),是合數還質數
行,但 O(\(N^2\)),慢到哭
給定一範圍 (1, x],求裡面的所有質數?
現在是 O(\(N^{\frac{3}{2}}\)),還是有點慢
質數
埃氏篩
具體作法
-先假設範圍內全部數字都是質數
-每遇到一個質數,就把它所有倍數都排除在外
-前往下一個數字
質數
埃氏篩
質數
埃氏篩
vector <bool> isPrime(MAXN, true);
void solve (){
for (int i = 2; i <= sqrt(MAXN); i++){
if (!isPrime[i]) continue;
for (int j = i*i; j <= MAXN; j += i) isPrime[j] = false;
}
}
質數
埃氏篩
那很難算,因為牽扯到一坨積分,我不想講
\(O(N\;log(log(N)))\)
\(O(N)\)
質數
線性篩
保證每個數字都 只會被篩到一次
(100):1、2、4、5、10、20、25、50、100
質數
線性篩
具體作法
-開個東西儲存目前篩出來的所有質數
-同樣從 2 開始往上跑,當跑到數字 \(i\) 時:
從目前篩出來的質數中由小到大遍歷
當遇到質數 \(p\) 時,把 \(i×p\) 排除在外
且若 \(p\;|\;i\),停止遍歷
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
is a prime
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(2×2=4,4\;will\;not\;be\;a\;prime\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2 | 2,break
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
is a prime
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(3×2=6,6\;will\;not\;be\;a\;prime\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(2 \nmid 3,continue\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(3×3=9,9\;will\;not\;be\;a\;prime\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
3 | 3,break
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(×2=8,8\;will\;not\;be\;a\;prime\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2 | 4,break
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
is a prime
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(5×2=10,10\;will\;not\;be\;a\;prime\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(2 \nmid 5,continue\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(5×3=15,15\;will\;not\;be\;a\;prime\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(3 \nmid 5,continue\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(5×5>15,break\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(×2=12,12\;will\;not\;be\;a\;prime\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2 | 6,break
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
is a prime
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(7×2=14,14\;will\;not\;be\;a\;prime\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(2 \nmid 7,continue\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(7×3>15,break\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\(×2 > 15,break\)
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
質數
線性篩
具體作法
vector <bool> isPrime(MAXN, true);
vector <int> prime;
void linear_sieve(){
for (int i = 2; i < N; i++){
if (isPrime[i]) prime.push_back(i);
for (auto to:prime){
if (to * i > N) break;
isPrime[i*to] = false;
if (i % to == 0) break;
}
}
}
工作區
prime
2
3
4
5
6
7
8
9
10
11
12
13
14
15
接著你就會發現有人動畫做到不耐煩了
質數
線性篩
所以這坨奇怪作法的核心概念是什麼?
e.g.
理論上,24 = 2 × 2 × 2 × 3,只會被 12 篩到
若我們在做 8 時,發現 2 | 8 卻沒 break
硬要做 8 × 3 = 24 的話,24 就會被篩到 2 次
質數
還要算上常數,複雜度並非唯一判斷
而且 log(log(N)) 在 N 夠小的情況下真的沒影響
@ MAXN \(\leq 2×10^8\):
埃氏篩 > 線性篩
@ MAXN \(> 2×10^8\):
線性篩 > 埃氏篩,約快個 10% 左右
同餘
由於答案的數字可能很大,請將其模 1e9 + 7 後輸出
由上可知:
cout << ans%MOD << '\n';
同餘
But Before That...
你真的知道數學上的 模 是什麼嗎?
所以我要怎麼表達 17 % 5 = 2 這種東西
同餘
所以我要怎麼表達 17 % 5 = 2 這種東西
\(17 \equiv 2\pmod{5}\)
17 與 2 在 mod 5 的情況下,餘數相同
e.g.
\(23 \equiv 2 \pmod{7}\),\(7 \mid (23-2)\)
同餘
e.g.
\(19 \equiv 3 \pmod{4}\),\(3 \equiv 19 \pmod{4}\)
這應該不用證明吧
e.g.
\(11 \equiv 5 \pmod{6},5 \equiv 1 \pmod{2}\)
\(11 \equiv 1 \pmod{2}\)
同餘
-把 mod 轉換一下
n | (a-b)、n | (b-c)
-利用整除公式合併他們
n | (a-b) + (b-c)
n | (a-c)
-再還原回來
\(a \equiv c \pmod{n}\)
同餘
e.g.
\(12 \equiv 2 \pmod{5}、13 \equiv 3 \pmod{5}\) ,則 \(25 \equiv 5 \pmod{5}\)
\(25 \equiv 0 \pmod{5},5 \mid 25\)
則 \((a+b) \equiv (c+d) \pmod{k}\)
(a+b) % k = [ (a%k) + (b%k) ] % k
同餘
則 \((a+c) \equiv (b+d) \pmod{k}\)
(a+b) % k = [ (a%k) + (b%k) ] % k
k | (a+c) - (b+d)
-老樣子,轉換
k | (a-b)、k | (c-d)
-其實跟剛剛有 87% 像
k | (a-b) + (c-d)
-還原
\((a+c) \equiv (b+d) \pmod{k}\)
同餘
則 \((a-c) \equiv (b-d) \pmod{k}\)
(a-b) % k = [ (a%k) - (b%k) ] % k
拜託啦,我真的懶得寫這個證明了
打 LaTeX 很累ㄟ
你就把剛剛的加號變成減號就好了
:pleading_face:
噢不,你也沒有拒絕的權利
同餘
則 \(ac \equiv bd \pmod{k}\)
ab % k = [ (a%k) (b%k) ] % k
拜託啦,我真的...
好咩,我寫就是了
e.g.
\(12 \equiv 2 \pmod{5}、13 \equiv 3 \pmod{5}\) ,則 \(156 \equiv 6 \pmod{5}\)
\(156 \equiv 1 \pmod{5}\)
同餘
則 \(ac \equiv bd \pmod{k}\)
ab % k = [ (a%k) (b%k) ] % k
好咩,我寫就是了
- 就算這裡只是一坨幹話,你也知道我做了什麼
k | (a-b)、k | (c-d)
- 那如果我偷偷在前面乘上 c,後面乘上 b 呢?
k | c(a-b)、k | b(c-d)
k | ca - cb、k | bc - bd
同餘
則 \(ac \equiv bd \pmod{k}\)
ab % k = [ (a%k) (b%k) ] % k
- 那如果我偷偷在前面乘上 c,後面乘上 b 呢?
k | c(a-b)、k | b(c-d)
k | ca - cb、k | bc - bd
- 答對ㄌ,兩式相加
k | ca - bd
- 然後呢?就還原 R,不然你想幹嘛
\(ac \equiv bd \pmod{k}\)
同餘
,則 \(a^c \equiv b^c \pmod{k}\)
自己延伸相乘公式的證明啦
現在半夜 3. 了 இ௰இ
\(a \equiv b \pmod{k}\) 乘上自己 c 次,很簡單吧
同餘
,則 \(ac \equiv bc \pmod{k}\)
k | ca - cb
-我連幹話都懶得掰了
k | (a-b)
-你為什麼要浪費時間讀這段文字
k | c(a-b)
-ㄟ你知道嗎,我今天早上喝了兩杯咖啡,比平常多一杯
\(ac \equiv bc \pmod{k}\)
同餘
加法 | (a+b) % k= [ (a%k) + (b%k) ]%k |
---|---|
減法 | (a-b) % k= [ (a%k) - (b%k) ]%k |
乘法 | ab % k= [ (a%k) (b%k) ]%k |
好,讓我們先 focus 在工程師公式(?)就好
cout << ans%MOD << '\n';
回歸問題,為何這麼做會吃 WA
人家就跟你說答案會很大,所以才要模數字
如果答案能讓你放在 ans 中,幹嘛多此一舉
所以你 ans 早就爆掉了 (*゜ー゜*)
同餘
加法 | (a+b) % k= [ (a%k) + (b%k) ]%k |
---|---|
減法 | (a-b) % k= [ (a%k) - (b%k) ]%k |
乘法 | ab % k= [ (a%k) (b%k) ]%k |
好,讓我們先 focus 在工程師公式(?)就好
#define ll long long int
const int MOD = 1e9 + 7;
ll Mod (ll a, int m = MOD){
return (a+m) % m;
}
ll Plus (ll a, ll b, int m = MOD){
return ((a%m) + (b%m))%m;
}
ll Minus (ll a, ll b, int m = MOD){
return ((a%m) - (b%m))%m;
}
ll Mult (ll a, ll b, int m = MOD){
return ((a%m) * (b%m))%m;
}
同餘
話說,除法呢,我可以用乘法反元素的邏輯去做嗎
顯然否。會爛得一蹋糊塗,跟我物理一樣
其實這本是今日範圍,但我發現講了這個
你們 21:00 前估計出不了電教了,所以留給演算法ㄅ
\(48 \equiv 3 \pmod{5},12 \equiv 2 \pmod{5}\)
\(4 \equiv \frac{3}{2} \pmod{5}\)?????
尤其是跟數學或自然有關的時候
歐拉函數
名詞介紹
e.g.
\((10) = 1、2、5、10,\phi(10) = 3\)
\((17) = 1、17,\phi(17) = 16\)
歐拉函數
名詞介紹
-一個大小為 n 的集合
-裡面的每個元素拿去 \(mod\;n\) 後,會得到相異 n 個元素
-翻譯年糕:for (int i = 0; i < n; i++),集合裡裝著 \(i + qn\)
e.g.
n = 7:{ 0, 1, 2, 3, 4, 5, 6 }
n = 9:{ 9, 10, 11, 12, 13, 14, 15, 16, 17 }
歐拉函數
名詞介紹
-字面上的意思
-翻譯年糕:裝著 0 ~ n-1 的 set
e.g.
n = 5:{ 0, 1, 2, 3, 4, 5 }
n = 8:{ 0, 1, 2, 3, 4, 5, 6, 7, 8 }
歐拉函數
名詞介紹
-只留下完全剩餘系中,與 n 互質的數
-翻譯年糕:
e.g.
n = 7:{ 1, 2, 3, 4, 5, 6 }
n = 8:{ 1, 11, 13, 15 }
for (int i = 0; i < n; i++)
if (gcd(i, n) = 1)
vec.push_back(i);
歐拉函數
名詞介紹
-字面上的意思
-翻譯年糕: 的定義就是它的大小
e.g.
n = 11:{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
n = 8:{ 1, 11, 13, 15 }
歐拉函數
歐拉函數
歐拉函數
然後呢,我們要怎麼求
則 \(\phi(N)=N\;\Pi_{i=1}^{n}(1 - \frac{1}{p_i})\)
\(e.g.\)
\(12 = 2^2×3\)
\(=12×\frac{1}{2}×\frac{2}{3}=4\)
\(\phi(12)=12×(1-\frac{1}{2})×(1-\frac{1}{3})\)
12 的非負最小簡化剩餘系:{ 1, 5, 7, 11 }
\(\phi(12)=4\)
歐拉函數
歐拉函數
然後呢,我們要怎麼求
則 \(\phi(N)=N\;\Pi_{i=1}^{n}(1 - \frac{1}{p_i})\)
證明ㄛ,Hmm ...
有個東西叫 中國剩餘定理
我們有教過嗎?沒有
我們今天會教嗎?不會
所以我們就跳過證明吧
歐拉函數
\(e.g.\)
(18) = 1, 2, 3, 6, 9, 18
i | φ(i) |
---|---|
1 | 1 |
2 | 1 |
3 | 2 |
6 | 2 |
9 | 6 |
18 | 6 |
\(1+1+2+2+6+6=18\)
歐拉函數
\(e.g.\)
\(\phi(18)=18-\phi(1)-\phi(2)-\phi(3)-\phi(6)-\phi(12)\)
\(= 18 - 1 - 1 - 2 - 2 - 6 = 6\)
歐拉函數
給定一範圍 (1, x],Q 筆詢問而且 Q 夠大
每筆詢問輸入一個 n,試問 \(\phi(n)\)?
利用第一個公式,只要列舉出質因數就能計算
O(\(\sqrt{n}\))
O(\(n^{\frac{3}{2}}\))
對,沒錯,有夠慢、超級慢
歐拉函數
給定一範圍 (1, x],Q 筆詢問而且 Q 夠大
每筆詢問輸入一個 n,試問 \(\phi(n)\)?
O\((n\,log\, n)\)
從小數字開始往上列舉倍數,把它扣掉自己的 \(\phi()\)
void sieve (int N){
for (int i = 1; i <= N; i++) phi[i] = i;
for (int i = 1; i <= N; i++)
for (int j = 2*i; j <= N; j += i)
phi[j] -= phi[i];
}
歐拉函數
給定一範圍 (1, x],Q 筆詢問而且 Q 夠大
每筆詢問輸入一個 n,試問 \(\phi(n)\)?
做完埃氏或線性篩後
對每個數用篩法 DP 質因數分解
再利用公式來 O(1) 解出歐拉函數
是ㄉ,這並非今日範圍,我沒有要教
歐拉定理
歐拉定理
\(e.g.\)
if gcd(m, n) = 1
than \(m^{\phi(n)} \equiv 1 \pmod{n}\)
\(m^{\phi(n)} \equiv 1 \pmod{n}\)
We know that gcd(3, 8) = 1
m = 3,n = 8,\(\phi(8) = 4\)
\(3^{\phi(8)} \equiv 1 \pmod{8}\)
\(3^{4} \equiv 1 \pmod{8}\)
\(81 \equiv 1 \pmod{8}\)
歐拉定理
if gcd(m, n) = 1
than \(m^{\phi(n)} \equiv 1 \pmod{n}\)
放心啦這個我會寫證明
\(\phi(n)\)
\((m\,a_i)\;mod\;n\) 之值皆不相同
而且遍歷過 N 後
這坨值又會形成 n 的非負最小簡化剩餘系
歐拉定理
if gcd(m, n) = 1
than \(m^{\phi(n)} \equiv 1 \pmod{n}\)
8 的 非負最小簡化剩餘系:{ 1, 3, 5, 7 }
m = 3,n = 8,\(\phi(8) = 4\)
\((3×1)\;mod\;8=3\)
\((3×3)\;mod\;8=1\)
\((3×5)\;mod\;8=7\)
\((3×7)\;mod\;8=5\)
\((m\,a_i)\;mod\;n\)
歐拉定理
if gcd(m, n) = 1
than \(m^{\phi(n)} \equiv 1 \pmod{n}\)
\((m\,a_1)(m\,a_2)...(m\,a_{\phi(n)}) \equiv a_1\,a_2\,...\,a_{\phi{n}} \pmod{n}\)
※ a 的編號是唬爛的
總之就是非負最小簡化剩餘系的其中一個元素
\(\Pi_{i = 1}^{\phi(n)}(a_i)×m^{\phi(n)} \equiv \Pi_{i=1}^{\phi(n)} \pmod{n}\)
歐拉定理
if gcd(m, n) = 1
than \(m^{\phi(n)} \equiv 1 \pmod{n}\)
\(\Pi_{i = 1}^{\phi(n)}(a_i)×m^{\phi(n)} \equiv \Pi_{i=1}^{\phi(n)} \pmod{n}\)
\(m^{\phi(n)} \equiv1 \pmod{n}\)
歐拉定理
if gcd(m, n) = 1
than \(m^{\phi(n)} \equiv 1 \pmod{n}\)
m = 3,n = 8,\(\phi(8) = 4\)
\((3×1)\;mod\;8=3\)
\((3×3)\;mod\;8=1\)
\((3×5)\;mod\;8=7\)
\((3×7)\;mod\;8=5\)
\((3×1) \equiv 3 \pmod{8}\)
\((3×3) \equiv 1 \pmod{8}\)
\((3×5) \equiv 7 \pmod{8}\)
\((3×7) \equiv 5 \pmod{8}\)
\((3×1)(3×3)(3×5)(3×7) \equiv 3×1×7×5 \pmod{8}\)
\(3^4(1×3×5×7) \equiv (3×1×7×5) \pmod{8}\)
歐拉定理
if gcd(m, n) = 1
than \(m^{\phi(n)} \equiv 1 \pmod{n}\)
m = 3,n = 8,\(\phi(8) = 4\)
\(3^4(1×3×5×7) \equiv (3×1×7×5) \pmod{8}\)
\(3^4 \equiv 1 \pmod{8}\)
費馬小定理
in other words, \(m^{n} \equiv m \pmod{n}\)
if [gcd(m, n) = 1] \(\wedge\) [n is a prime]
than \(m^{n-1} \equiv 1 \pmod{n}\)
\(e.g.\)
We know that 5 is a prime,gcd (3, 5) = 1
m = 3,n = 5,\(\phi(n) = 4\)
\(m^{n-1} \equiv 1 \pmod{n}\)
\(3^{4} \equiv 1 \pmod{5}\)
\(81 \equiv 1 \pmod{5}\)
費馬小定理
in other words, \(m^{n} \equiv m \pmod{n}\)
if [gcd(m, n) = 1] \(\wedge\) [n is a prime]
than \(m^{n-1} \equiv 1 \pmod{n}\)
p-1
費馬小定理
in other words, \(m^{n} \equiv m \pmod{n}\)
if [gcd(m, n) = 1] \(\wedge\) [n is a prime]
than \(m^{n-1} \equiv 1 \pmod{n}\)
p-1
歐拉定理、費馬小定理
廣義歐拉定理
歐拉定理、費馬小定理
廣義歐拉定理
廣義歐拉定理
歐拉定理、費馬小定理
對,我還是沒有要講,你想多了
如果我要將同餘定理推廣到除法
則我必須保證除的數 m 與模的數 n 互質
可得
古之寒假必有活。
寒假者,所以資飯睡覺打冬冬也。
人非孤而得樂者,孰能不報?
知而不報名,再無機會,終留憾也。
建電學長,其報寒訓固先乎吾,吾從而習之;
北資學姊,其報寒訓亦先乎吾,吾從而習之。
寒訓者也, 豈因其先後而不得樂乎?
是故無論建北,無長無少,寒訓所存,樂之所存也。
寒訓報名截止最後一個禮拜,快點來報啦QAQ
By repkironca