數學
aka 高中數學 in 資訊
簡介
競賽數學主要分 ACGN 四大類
Algebra 代數
Combinatory 組合
Geometry 幾何
Number theory 數論
不是 Animation, Comic, Game, Novel 啦
高中資訊用到的數學
\(C \approx N > A > G\)
然後要會一點向量、線性代數、群論
大學資訊用到的數學
A 的比例高好多,但因為我也不會大學資訊就不排了
有一堆多項式詭譎
如果你去年聽過了
這裡空空的,什麼都沒留下
我不相信有人有把去年刷完
數論
同餘
a 與 b 在模 p 下同餘若且唯若 (a-b)%p == 0
這裡的 p 不一定是質數
加法、減法、乘法
const int mod=998244353;
void add(int& x,int y){
x+=y;
x-=mod*(x>=mod);
x+=mod*(x<0);
}
int mul(int x,int y){
return 1ll*x*y%mod;
}
除法
在模質數底下,不能整除怎麼辦
\(\frac{x}{y} = z \implies x \equiv y \cdot z \pmod p\)
假設我們有 \(y \cdot b \equiv 1 \pmod p\)
那麼 \( x \cdot b \equiv b \cdot y \cdot z \equiv z \pmod p\)
也就是說 \( z \equiv x \cdot b \pmod p \)
這樣就可以算了
問題就是要怎麼算出那個 b
有三種方法
- 費馬小定理
- 酷酷公式
- 貝祖定理
模逆元
費馬小定理
$$ a^{p-1} \equiv 1 \pmod p$$
也就是說 \( a \cdot a^{p-2} \equiv 1 \pmod p\)
代表 \(b = a^{p-2}\)
直接用快速冪做就好了
快速冪
\( a^n = (a^{n/2})^2 \cdot a [a\%2==1] \)
O(logn)
酷酷公式
int inv(int x){
return x==1?1:mul(mod-mod/x,inv(mod%x));
}
據說是 O(logn)
去年我說我不會證,現在我是根本不知道複雜度
隨便啦,很快
貝祖定理
對於所有整數 \(a,b\) 存在無限多組整數 \(x,y\) 滿足 $$ ax + by = gcd(a,b) $$
遞迴
假設我們有了 \( bx' + (b\%a)y' = 1\)
要怎麼推出 \(ax + by = 1\)的解
注意到 \(a\%b = a - \lfloor \frac{a}{b} \rfloor \cdot b\)
$$bx' + (a\%b) y' = 1 $$
$$ bx' + (a - \lfloor \frac{a}{b} \rfloor b)y' = 1 $$
$$ ay' + b(x' - \lfloor \frac{a}{b} \rfloor y') = 1$$
是唯一能用在合數的模逆元方法
code
int ext(int a,int b,int& x,int& y){
if(b==0){
x=1;
y=0;
return a;
}
int d=ext(b,a%b,y,x);
y-=a/b*x;
return d;
}
GCD
輾轉相除法
或是有酷酷的內建函式 __gcd 可以用
範例 code
const int mod=998244353;
void add(int& x,int y){
x+=y;
x-=mod*(x>=mod);
x+=mod*(x<0);
}
int mul(int x,int y){
return 1ll*x*y%mod;
}
int po(int x,int y){
int z=1;
while(y){
if(y&1){
z=mul(z,x);
}
x=mul(x,x);
y>>=1;
}
return z;
}
int inv(int x){
return po(x,mod-2);
}
int inv(int x){
return x==1?1:mul(mod-mod%x,inv(mod%x));
}
add(x,1);
x=mul(x,2);
__gcd(3,5);
OJDL 7044
模逆元練習
這題太神隨意看題解
質數
判斷質數
從 1 掃到 \( \sqrt n\) ,如果裡面有整數是因數就不是質數,反之則是
其他方法
找到 1 到 n 的所有質數
照上面的作法會是 O(n^1.5)
改進一下
從 1 到 n 掃過一遍,每次更新他的所有倍數
沒被更新過的就是質數
\( O( \frac{n}{1} + \frac{n}{2} + \dots + \frac{n}{n}) = O(n log(n)) \)
因數篩
小優化
只跑過質數的倍數
\( O( \frac{n}{2} + \frac{n}{3} + \dots )= O(n loglog(n)) \)
上一張的可以用在找出一個數的所有因數
由此也可得 1 到 n 所有數的因數數量和 = O(nlogn)
線性篩
如果能讓每個數都被篩過一次,那就可以 O(n) 算完了
所以我們會想要讓每個合數被他的最小質因數算到
vector<int> vis,pr;
for(int i=2;i<n;i++){
if(!vis[i]){
pr.push_back(i);
}
for(auto h:pr){
if(h*i>n){
break;
}
vis[h*i]=1;
if(i%h==0){
break;
}
}
}
Code
線性篩求歐拉函數
歐拉函數 \(\varphi(n)\) 代表 n 以下有多少數與 n 互質
有積性
其實還有很多東西都可以線性篩求
除了有積性的之外 least prime factor 等等也可以
code
vector<int> vis,pr,phi;
for(int i=2;i<n;i++){
if(!vis[i]){
pr.push_back(i);
phi[i]=i-1;
}
for(auto h:pr){
if(h*i>n){
break;
}
vis[h*i]=1;
if(i%h==0){
phi[i*h]=h*phi[i];
break;
}
else{
phi[i*h]=phi[h]*phi[i];
}
}
}
求最小的 \(n\) 使 \(n^n \ mod \ 10^9 = x\)
先把 10 拆成 2*5, 那你想要把 \(x \ mod\ 2^9\) 跟 \(x \ mod \ 5^9\) 算出來
現在我們要看 \(n^n \ mod \ 2^9\) 跟 \(n^n \ mod\ 5^9\) 的循環節是多少
先看 2 的部分,那就是 \((n \ mod\ 2^9)^{n \ mod\ \phi(2^9)}\),因此循環節是 \(lcm(2^9,\phi(2^9))\)
5 的部分也是一樣
那求出循環節後就可以直接對循環節內的每個數求答案
然後再中國剩餘就好
題目
組合
組合數 \(C^n_k\)
算法:主要有三種
- \(n \leq 1000: O(n^2) \) Pascal Triangle
- \(n \leq 1000000\) 多次詢問:O(n) 蓋出 frac 表,然後用 $$ C^n_k = \frac{n!}{k! \cdot (n-k)!} $$
- (mod 質數) \( n \leq 10^{18}, p \leq 1000\) => Lucas Theorem
在 n 個裡面取 k 個的方法數
AB 跟 BA 好難歸納
如果是 AA 跟 BB 呢
把第偶數個的 A 換成 B,B 換成 A,可以發現答案不變
那麼題目變成不能砍 AA 跟 BB
怎麼做?
他跟 "把 2n 個數配對,不能有一對數相同" 很像
事實上要是他們可以配對那一定找到一個方法刪除連續的兩個值
打架!
結論是只要 A 的個數跟 B 的個數都不超過 N/2 就合法
所以我們可以枚舉不合法的時候的 A 的數量,假設是 k
那麼就是 C(n,k) * 2^(n-k)
就做完了
雖然我當初好像不是這樣寫
一個小細節是這題的 N 很大
多考了一個線性預處理+O(1) 查 C(n,k)
你會需要 ifac[i] = fac[i]^(-1)
然後這可以倒著作回來
Lucas theorem
\( C^n_k \equiv \prod_{i=0} C^{n_i}_{k_i} \pmod p \)
\(n_i\) 跟 \(k_i\) 分別是 n 跟 k 轉成 p 進位每一個位的位元
例題:ARC 137 D
排容
我去年居然有講到這個...
要計算幾個集合併集的大小,我們要先將所有單個集合的大小計算出來,然後減去所有兩個集合相交的部分,再加回所有三個集合相交的部分,再減去所有四個集合相交的部分,依此類推,一直計算到所有集合相交的部分。
copy by wikipedia
首先答案 = 橫排滿足條件 + 直排滿足條件 - 都滿足條件
前兩個很好算,比較難的是都滿足條件的那個
可以發現橫排直排都滿足條件,那麼他們顏色是相同的,且所有滿足條件的橫排的顏色都相同
所以假設我們固定其中一個橫排的顏色,那麼可以算出來滿足條件的個數
考慮對橫排個數排容,至少有 i 個橫排滿足條件的選法是
$$C_i^n(3^{n(n-i)}-(2^{n-i} - 1)^n)$$
所以都滿足條件的答案是
$$\sum_{i=1}^n (-1)^{i+1} \cdot C_i^n(3^{n(n-i)}-(2^{n-i} - 1)^n)$$
排容才不只這樣
排容才不只這樣
再觀察一下,排容的核心想法是什麼
扣掉多算的
讓每個答案都被算到一次
本來這兩邊應該要放一題但我找不到 judge
偷偷打個題敘在這
左. 給定 n<=5000, r<=1e9, B[1...n], 求出有幾種陣列 A[1...n] 使得 A[i] <= A[i+1], A[i]<=B[i]且值域在 [1,r] 間
右. 給一棵樹,n<=2000,求有多少種 coloring,可行的顏色是 1~n 且不重複,使得你可以做以下操作 n-1 次:選擇點 u,v 使得 abs(col[u] - col[v]) = 1 且 u-v 有邊,並把所有跟 u 同顏色的點 w. col[w]:=col[v]
構造題
我要成為方格王
屏東方格王是一所積極新創... 的 amano_hina
- 那個形狀真的很醜耶,來把他變漂亮一點
- 你可以拼出 2*4、3*3 挖一個角、兩個 2*2 接在一起
- 所以 4k 的話拿 2*4 去拼就好
- 4k+2 驗一下奇偶性會發現拼不滿,所以 2*4 也可以解決
- 接下來我們想要 reduce 長度
- 手算會發現 5*5 會多 5 格,然後 7*7 好像也會多 5 格
- 拿 3*3-1 放在左上角然後把 2*4 放在邊邊的話可以把 4k+3 -> 4k+1 耶讚
- 手構發現 9*9, 13*13 都可以 1 格(要用到兩個 2*2 接在一起)
- 所以我們想要讓邊長 -8,那就是構出 9*9-1
- 真的可以,做完了
- 好好實作 :)
真的是通靈之類的
提示:對角線
提示:做一做砍一半重構
線代相關
高斯消去
把對角線以下的消掉
數學-3
By alvingogo
數學-3
- 150