二项式定理
( x + y ) k = ∑ i = 0 k x i y k − i × C i k (x+y)^{k}=\sum_{i=0}^{k} x^{i} y^{k-i} \times C_{i}^{k} (x+y)k=i=0∑kxiyk−i×Cik
欧拉定理
如果正整数
n
n
n 和整数
a
a
a 互质, 那么就有
a
φ
(
n
)
≡
1
(
m
o
d
n
)
a^{\varphi(n)} \equiv 1\pmod n
aφ(n)≡1(modn)
扩展欧拉定理
a b m o d m = b m o d φ ( m ) a^b \bmod m = b \bmod \varphi (m) abmodm=bmodφ(m)
当 gcd ( a , m ) ≠ 1 \gcd(a,m) \not= 1 gcd(a,m)=1 时, a b ≡ a c ( m o d m ) a^b \equiv a^c \pmod{m} ab≡ac(modm),其中 c c c 在 b < φ ( m ) b < \varphi(m) b<φ(m) 时为 b b b,否则为 b m o d φ ( m ) + φ ( m ) b \bmod \varphi(m) + \varphi(m) bmodφ(m)+φ(m)
费马小定理
p
p
p 为质数,
a
a
a 为任意自然数, 则
a
p
≡
a
(
m
o
d
p
)
⟺
a
p
−
1
≡
1
(
m
o
d
p
)
a^{p} \equiv a\pmod p \iff a^{p-1} \equiv 1 \pmod p
ap≡a(modp)⟺ap−1≡1(modp)
快速幂
快速幂是对倍增思想的应用,可以以 log \log log 级别的复杂度求 a k a^k ak。
若 k k k 为偶数,则 a k = a k 2 × a k 2 a^k = a^{\frac{k}{2}} \times a^{\frac{k}{2}} ak=a2k×a2k。
若 k k k 为奇数,则 a k = a 1 × a k − 1 a^k = a^1 \times a^{k-1} ak=a1×ak−1。奇数减一为偶数。
int ksm(int a, int k, int p) {
int res = 1;
while (k) {
if (k & 1) res = res * a % p;
a = a * a % p;
k >>= 1;
}
return res % p;
}
当指数极大,且 p p p 为质数时,可以降幂,步骤如下
a n = a k × ( p − 1 ) + r = a p − 1 k × a r a^n = a^{k \times (p - 1) + r} = a{^{p-1}}^k \times a^r an=ak×(p−1)+r=ap−1k×ar
根据费马小定理
a p − 1 ≡ 1 ( m o d p ) a^{p-1} \equiv 1 \pmod p ap−1≡1(modp)
( a p − 1 ) m o d p = 1 (a^p - 1) \bmod p = 1 (ap−1)modp=1
a n = a r a^n = a^r an=ar
有
r = n m o d ( p − 1 ) r = n\bmod (p-1) r=nmod(p−1)
线性筛
线性筛质数可求 1 ∼ n 1 \sim n 1∼n 所有的质数。
对于每一个数 i i i,标记所有小于 「 i i i 的最小质因子」 的质数 × i \times i ×i 的数为合数。如 i = 77 = 7 × 11 i=77=7 \times 11 i=77=7×11,那么 2 × 77 , 3 × 77 , 5 × 77 2 \times 77, \ 3\times 77, \ 5 \times 77 2×77, 3×77, 5×77 会标记为合数。
想证明该算法为线性且正确,只需证明没有重复筛,没有多筛,没有漏筛三点即可。其中没有重复筛显然成立。
令一个合数 x = ∏ j = 1 n p j ∧ p j < p j + 1 x = \prod _{j=1}^n p_j \land p_j < p_{j+1} x=∏j=1npj∧pj<pj+1。
筛掉该合数的机会为 i = ∏ j = 1 n p j p j ∧ x = p j × ∏ j = 1 n p j p j i = \frac{\prod _{j=1}^n p_j}{p_j} \land x = p_j \times \frac{\prod _{j=1}^n p_j}{p_j} i=pj∏j=1npj∧x=pj×pj∏j=1npj 。因为标记所有小于 「 i i i 的最小质因子」 的质数 × i \times i ×i 的数为合数,所以 j = 1 j = 1 j=1。没有重复筛成立。
有 ∏ j = 1 n p j p 1 < x \frac{\prod _{j=1}^n p_j}{p_1} < x p1∏j=1npj<x,所以 i = ∏ j = 1 n p j p 1 i = \frac{\prod _{j=1}^n p_j}{p_1} i=p1∏j=1npj 时将 x x x 标记为合数。没有漏筛成立。
int pr[N + 5], vis[N + 5] = {1, 1}, n, tot;
void init() {
for (int i = 1; i <= N; i++) {
if (!vis[i]) pr[++tot] = i;
for (int j = 1; j <= tot && i * pr[j] <= N; j++) {
vis[i * pr[j]] = 1;
if (i % pr[j] == 0) break;
}
}
}
逆元
逆元与除法取模有关,具体的,如果
a
b
m
o
d
m
=
a
×
x
m
o
d
m
\frac{a}{b} \bmod m = a \times x \bmod m
bamodm=a×xmodm,我们把
x
x
x 叫作
b
b
b 在模
m
m
m 意义下的逆元,记做
b
−
1
b^{-1}
b−1。有
b
×
x
≡
1
(
m
o
d
m
)
b \times x \equiv 1\pmod{m}
b×x≡1(modm)
求质数逆元常见的方式是费马小定理。 如果模数
p
p
p 为一个质数,而整数
a
a
a 不是
p
p
p 的倍数,则有
a
p
−
1
≡
1
(
m
o
d
p
)
⇕
a
p
−
2
≡
a
−
1
(
m
o
d
p
)
a^{p-1} \equiv 1\pmod{p} \\ \Updownarrow \\ a^{p-2} \equiv a^{-1} \pmod{p}
ap−1≡1(modp)⇕ap−2≡a−1(modp)
所以
a
a
a 的逆元为
a
p
−
2
a^{p-2}
ap−2。
如果模数
m
m
m 不为质数,但
b
b
b 与
m
m
m 互质,那么可以用扩展欧几里得求逆元。因为扩展欧几里得可以求线性同余方程
b
×
x
≡
1
(
m
o
d
m
)
⇕
b
×
x
m
o
d
m
=
1
⇕
b
x
+
(
−
m
y
)
=
1
b \times x \equiv 1\pmod{m} \\ \Updownarrow \\ b \times x \bmod m = 1 \\ \Updownarrow \\ bx + (- my) = 1
b×x≡1(modm)⇕b×xmodm=1⇕bx+(−my)=1
exgcd 求解即可。
欧拉函数
欧拉函数的符号为 φ \varphi φ, φ ( n ) \varphi(n) φ(n) 为小于等于 n n n 与 n n n 互质的数的个数。
对于一个质数
p
p
p 和一个整数
k
k
k,有
φ
(
p
)
=
p
−
1
φ
(
p
k
)
=
p
k
−
p
k
k
=
p
k
−
p
k
−
1
\varphi(p) = p - 1 \\ \varphi(p^k) = p^k - \frac{p^k}{k} = p ^k - p^{k-1}
φ(p)=p−1φ(pk)=pk−kpk=pk−pk−1
对于一个数
n
n
n,将他分解质因数
n
=
∏
i
=
1
k
p
i
a
i
φ
(
n
)
=
φ
(
∏
i
=
1
k
p
i
a
i
)
=
∏
i
=
1
k
p
i
a
i
−
p
i
a
i
−
1
=
∏
i
=
1
k
p
i
a
i
(
1
−
1
p
i
)
=
n
×
∏
i
=
1
k
(
1
−
1
p
i
)
n = \prod_{i=1}^k p_i^{a_i} \\ \varphi(n) = \varphi (\prod_{i=1}^k p_i^{a_i}) = \prod_{i=1}^k {p_i}^{a_i} - {p_i}^{a_i - 1} \\ = \prod_{i=1}^k {p_i}^{a_i} (1 - \frac{1}{p_i}) = n \times \prod_{i=1}^k (1 - \frac{1}{p_i})
n=i=1∏kpiaiφ(n)=φ(i=1∏kpiai)=i=1∏kpiai−piai−1=i=1∏kpiai(1−pi1)=n×i=1∏k(1−pi1)
以上为欧拉函数的通式。
众所周知,欧拉函数为积性函数,有 φ ( a b ) = φ ( a ) φ ( b ) \varphi(ab) = \varphi(a)\varphi(b) φ(ab)=φ(a)φ(b),其中 a a a 与 b b b 互质。所以可以用线性筛的方法在求质数表的同时求欧拉函数。需要用到以下性质,其中 p p p 为质数
-
φ ( p ) = p − 1 \varphi(p) = p - 1 φ(p)=p−1
-
若 p ∣ i p|i p∣i,那么 φ ( i × p ) = φ ( i ) × p \varphi(i \times p) = \varphi(i) \times p φ(i×p)=φ(i)×p,证明略。
-
若 p ∤ i p \not| \ \ i p∣ i,那么 φ ( i × p ) = φ ( i ) × ( p − 1 ) \varphi(i \times p) = \varphi(i) \times (p-1) φ(i×p)=φ(i)×(p−1)。
略证:若 p ∤ i p\not| \ \ i p∣ i,那么 i i i 与 p p p 互质,根据积性函数的性质 φ ( i × p ) = φ ( i ) × φ ( p ) = φ ( i ) × ( p − 1 ) \varphi(i \times p) = \varphi(i) \times \varphi(p) = \varphi(i) \times (p - 1) φ(i×p)=φ(i)×φ(p)=φ(i)×(p−1)。
int pr[N + 5], vis[N + 5] = {1, 1}, phi[N + 5], n, tot;
void init() {
for (int i = 1; i <= N; i++) {
if (!vis[i]) {
pr[++tot] = i;
phi[i] = i - 1;
}
for (int j = 1; j <= tot && i * pr[j] <= N; j++) {
vis[i * pr[j]] = 1;
if (i % pr[j] == 0) {
phi[i * pr[j]] = phi[i] * pr[j];
break;
}
phi[i * pr[j]] = phi[i] * (pr[j] - 1);
}
}
}