数论基本概念
1. 整除法
n = a k + r ( 0 ≤ r < a ) → k = ⌊ n a ⌋ n = ak + r(0 \le r < a) \to k = \lfloor \frac{n}{a} \rfloor n=ak+r(0≤r<a)→k=⌊an⌋
2. 算数基本定理
p
i
p_i
pi 为素数,且
p
i
<
p
i
+
1
p_i < p_{i + 1}
pi<pi+1,则有:
n
=
p
1
a
1
p
2
a
2
⋯
p
m
a
m
n = p_1^{a_1} p_2^{a_2} \cdots p_m ^ {a_m}
n=p1a1p2a2⋯pmam
3. 最大公约数与最小公倍数
gcd ( a , b ) × lcm ( a , b ) = gcd ( a , b ) × a × b gcd ( a , b ) = a × b \gcd (a,b) \times \operatorname{lcm} (a,b) = \gcd (a,b) \times \frac{a \times b}{\gcd(a,b)} = a \times b gcd(a,b)×lcm(a,b)=gcd(a,b)×gcd(a,b)a×b=a×b
4. 求一个数的约数个数
一个数的每个因子均由若干个素因子构成,第
i
i
i 个素因子共有
i
+
1
i + 1
i+1 种取法,所以总个数为(
k
k
k 为素因子的总个数):
∏
i
=
1
k
(
a
i
+
1
)
\prod_{i = 1}^{k} (a_i + 1)
i=1∏k(ai+1)
代码如下:
int divisor (int n)//算数基本定理
{
int tot = 1;
for (int i = 2;i * i <= n;++i)
{
if (n % i == 0)
{
int cnt = 0;
while (n % i == 0) n /= i,++cnt;//素因子i 在 num 中的个数
tot *= (cnt + 1);
}
}
if (n > 1) tot *= 2;//剩下的 n 也为素数的情况
return tot;
}
int divisor_direct (int n)//直接暴力枚举
{
int cnt = 0;
for (int i = 1;i * i <= n;++i)
{
if (n % i == 0)
{
++cnt;
if (n / i != i) ++cnt;//完全平方数时会重复计算
}
}
return cnt;
}
素数筛法
1. 朴素筛法
将每一个数的所有倍数都筛去,时间复杂度为: O ( n 2 + n 3 + ⋯ + 1 ) O(\frac{n}{2} + \frac{n}{3} + \cdots + 1) O(2n+3n+⋯+1)。所以当 lim ( n → ∞ ) \lim(n \to \infty) lim(n→∞) 时,近似为 O ( n log n ) O(n\log n) O(nlogn)。
2. 常数优化
枚举小的那个因子。
for (int i = 2;i * i <= n;++i)
if (!flag[i])
for (int j = i * i;j <= n;j += i) flag[j] = 1;
3. 线性筛
时间复杂度为 O ( n ) O(n) O(n)。
void work (int n)//保证每个数最多被筛一次
{
for (int i = 2;i <= n;++i)
{
if (!flag[i]) p[++cnt] = i;//素数
for (int j = 1;j <= cnt;++j)
{
if (i * p[j] > n) break;//边界
flag[i * p[j]] = 1;//p[j] 是 i * p[j] 的最小素因子
if (i % p[j] == 0) break;//之后 p[j] 不为 i * p[j] 的最小素因子
//若 p[j] = 2,i = 4,则之后 p[j] = 3,i = 4 不符合条件。否则 12 = 2*6 = 3 * 4 被筛的次数 > 1
}
}
}
欧几里得算法
1. 辗转相减
若 a > b a > b a>b,则 gcd ( a , b ) = gcd ( a − b , b ) \gcd (a,b) = \gcd (a - b,b) gcd(a,b)=gcd(a−b,b)。
2. 辗转相除
若 a > b a > b a>b,则 gcd ( a , b ) = gcd ( b , a m o d b ) \gcd (a,b) = \gcd (b,a \bmod b) gcd(a,b)=gcd(b,amodb)。
int gcd (int a,int b)
{
if (a < b) swap (a,b);
return (!b) ? a : gcd (b,a % b);
}
扩展欧几里得算法
由欧几里得算法可知
a
x
+
b
y
=
gcd
(
a
,
b
)
ax + by = \gcd (a,b)
ax+by=gcd(a,b) 一定存在一组解。那么求解
a
x
+
b
y
=
c
ax + by = c
ax+by=c 时,过程如下:
a
x
+
b
y
=
c
(
a
>
b
)
设
a
x
′
+
b
y
′
=
gcd
(
a
,
b
)
则辗转相减知
(
a
−
b
)
×
x
1
+
b
×
y
1
=
gcd
(
a
,
b
)
∴
a
×
x
1
+
b
×
(
y
1
−
x
1
)
=
gcd
(
a
,
b
)
∴
x
=
x
1
,
y
=
y
1
−
x
1
由辗转相除代替辗转相减,则有
b
×
x
1
+
a
m
o
d
b
×
y
1
=
gcd
(
a
,
b
)
∵
a
m
o
d
b
=
a
−
⌊
a
b
⌋
×
b
∴
b
×
x
1
+
(
a
−
⌊
a
b
⌋
×
b
)
×
y
1
=
gcd
(
a
,
b
)
∴
a
×
y
1
+
b
×
(
x
1
−
⌊
a
b
⌋
×
y
1
)
=
gcd
(
a
,
b
)
∴
x
=
y
1
,
y
=
x
1
−
⌊
a
b
⌋
×
y
1
ax + by = c(a > b)\\\texttt{设 } ax' + by' = \gcd (a,b)\\\texttt{则辗转相减知 } (a - b) \times x_1 + b \times y_1 = \gcd (a,b)\\\therefore a \times x_1 + b \times (y_1 - x_1) = \gcd (a,b)\\\therefore x = x_1,y = y_1 - x_1\\\\\texttt{由辗转相除代替辗转相减,则有 } b \times x_1 + a \bmod b \times y_1 = \gcd (a,b)\\\because a \bmod b = a - \lfloor \frac{a}{b} \rfloor \times b\\\therefore b \times x_1 + (a - \lfloor \frac{a}{b} \rfloor \times b) \times y_1 = \gcd (a,b)\\\therefore a \times y_1 + b \times (x_1 - \lfloor \frac{a}{b} \rfloor \times y_1) = \gcd (a,b)\\\therefore x = y_1,y = x_1 - \lfloor \frac{a}{b} \rfloor \times y_1
ax+by=c(a>b)设 ax′+by′=gcd(a,b)则辗转相减知 (a−b)×x1+b×y1=gcd(a,b)∴a×x1+b×(y1−x1)=gcd(a,b)∴x=x1,y=y1−x1由辗转相除代替辗转相减,则有 b×x1+amodb×y1=gcd(a,b)∵amodb=a−⌊ba⌋×b∴b×x1+(a−⌊ba⌋×b)×y1=gcd(a,b)∴a×y1+b×(x1−⌊ba⌋×y1)=gcd(a,b)∴x=y1,y=x1−⌊ba⌋×y1
不断递归得到
gcd
(
a
,
b
)
×
x
+
0
×
y
=
gcd
(
a
,
b
)
\gcd (a,b) \times x + 0 \times y = \gcd (a,b)
gcd(a,b)×x+0×y=gcd(a,b),得到特解
x
=
1
,
y
=
0
x = 1,y = 0
x=1,y=0。
int exgcd (int a,int b,int &x,int &y)
{
int g = a;
if (b)
{
g = exgcd (b,a % b,x,y);
x -= (a / b) * y;
swap (x,y);
}
else x = 1,y = 0;//一组特解
return g;
}
设 k 1 = a gcd ( a , b ) , k 2 = b gcd ( a , b ) k_1 = \dfrac{a}{\gcd (a,b)},k_2 = \dfrac{b} {\gcd (a,b)} k1=gcd(a,b)a,k2=gcd(a,b)b,显然 gcd ( k 1 , k 2 ) = 1 \gcd (k_1,k_2) = 1 gcd(k1,k2)=1。设 x , y x,y x,y 的最小变化单位是 d 1 , d 2 d_1,d_2 d1,d2,则此时 k 1 = d 2 , k 2 = d 1 k_1 = d_2,k_2 = d_1 k1=d2,k2=d1,所以通解是:
{ x = x + k × b gcd ( a , b ) y = y − k × a gcd ( a , b ) k ∈ Z \begin{cases}x = x + k \times \dfrac{b}{\gcd(a,b)}\\y = y - k \times \dfrac{a}{\gcd(a,b)}\\k \in \Z \\\end{cases} ⎩ ⎨ ⎧x=x+k×gcd(a,b)by=y−k×gcd(a,b)ak∈Z
欧拉函数
1. 定义
ϕ ( n ) \phi(n) ϕ(n) 表示小于等于 n n n 的正整数与 n n n 互质的个数。 并且规定 ϕ ( 1 ) = 1 \phi(1) = 1 ϕ(1)=1。
2. 积性函数
设
p
p
p 为质数,求
ϕ
(
p
k
)
\phi(p^k)
ϕ(pk),也就是总数减去所有
p
p
p 的倍数。
ϕ
(
p
k
)
=
p
k
−
(
p
k
÷
p
)
=
p
k
−
p
k
−
1
=
(
p
−
1
)
×
p
k
−
1
\phi(p^k) = p^k - (p^k \div p) = p^k - p^{k - 1} = (p - 1) \times p^{k - 1}
ϕ(pk)=pk−(pk÷p)=pk−pk−1=(p−1)×pk−1
同理,求
ϕ
(
p
1
k
1
×
p
2
k
2
)
\phi(p_1 ^ {k_1} \times p_2 ^ {k_2})
ϕ(p1k1×p2k2),也就是总数减去
p
1
,
p
2
p_1,p_2
p1,p2 的倍数,然后再加上
p
1
×
p
2
p_1 \times p_2
p1×p2 的倍数。
∴
ϕ
(
p
1
k
1
p
2
k
2
)
=
p
1
k
1
p
2
k
2
−
p
1
k
1
−
1
p
2
k
2
×
p
1
k
1
p
2
k
2
−
1
+
p
1
k
1
−
1
p
2
k
2
−
1
∴
ϕ
(
p
1
k
1
p
2
k
2
)
=
ϕ
(
p
1
k
1
)
×
ϕ
(
p
2
k
2
)
\therefore \phi ({p_1} ^ {k_1} {p_2} ^ {k_2}) = {p_1} ^ {k_1} {p_2} ^ {k_2} - {p_1} ^ {{k_1} - 1} {p_2} ^ {k_2} \times {p_1} ^ {k_1} {p_2} ^ {{k_2} - 1} + {p_1} ^ {{k_1} - 1}{p_2} ^ {{k_2} - 1}\\ \therefore \phi ({p_1} ^ {k_1} {p_2} ^ {k_2}) = \phi({p_1} ^ {k_1}) \times \phi({p_2} ^ {k_2})
∴ϕ(p1k1p2k2)=p1k1p2k2−p1k1−1p2k2×p1k1p2k2−1+p1k1−1p2k2−1∴ϕ(p1k1p2k2)=ϕ(p1k1)×ϕ(p2k2)
3. 计算通式
将
n
n
n 进行质因数分解,则有:
n
=
p
1
a
1
p
2
a
2
⋯
p
m
a
m
∴
ϕ
(
n
)
=
∏
i
=
1
m
p
i
k
i
−
1
×
(
p
i
−
1
)
=
∏
i
=
1
m
p
i
k
i
−
1
×
p
i
×
(
p
i
−
1
)
÷
p
i
=
n
×
∏
i
=
1
m
p
i
−
1
p
i
n = p_1^{a_1} p_2^{a_2} \cdots p_m ^ {a_m}\\ \therefore \phi (n) = \prod_{i = 1}^{m} p_i^{k_i - 1} \times (p_i - 1) = \prod_{i = 1}^{m} p_i^{k_i - 1} \times p_i \times(p_i - 1) \div p_i = n \times \prod_{i = 1}^m \dfrac{p_i - 1}{p_i}
n=p1a1p2a2⋯pmam∴ϕ(n)=i=1∏mpiki−1×(pi−1)=i=1∏mpiki−1×pi×(pi−1)÷pi=n×i=1∏mpipi−1
4. 性质
-
若 m , n m,n m,n 互质,则 ϕ ( m n ) = ϕ ( m ) × ϕ ( n ) \phi(mn) = \phi(m) \times \phi(n) ϕ(mn)=ϕ(m)×ϕ(n),此函数为积性函数。证明相当于是 3 3 3。
-
若 p p p 为质数,则 ϕ ( p ) = p − 1 \phi(p) = p - 1 ϕ(p)=p−1。
-
若 n n n 为奇数,则 ϕ ( 2 n ) = ϕ ( n ) \phi(2n) = \phi(n) ϕ(2n)=ϕ(n)。
∵ n = 2 k + 1 ( k ∣ Z ) ∴ n 与 2 互质 又 ∵ 当 m , n 互质时, ϕ ( m n ) = ϕ ( m ) × ϕ ( n ) ∴ ϕ ( 2 n ) = ϕ ( 2 ) × ϕ ( n ) ∵ ϕ ( 2 ) = 1 ∴ ϕ ( 2 n ) = ϕ ( n ) × 1 = ϕ ( n ) \because n = 2k + 1(k \mid \Z)\\ \therefore n\ 与\ 2\ 互质\\ 又 \because 当\ m,n\ 互质时,\phi (mn) = \phi (m) \times \phi (n)\\ \therefore \phi (2n) = \phi (2) \times \phi (n)\\ \because \phi(2) = 1\\ \therefore \phi (2n) = \phi (n) \times 1 = \phi (n) ∵n=2k+1(k∣Z)∴n 与 2 互质又∵当 m,n 互质时,ϕ(mn)=ϕ(m)×ϕ(n)∴ϕ(2n)=ϕ(2)×ϕ(n)∵ϕ(2)=1∴ϕ(2n)=ϕ(n)×1=ϕ(n) -
若 p p p 能整除 n p \dfrac{n}{p} pn,则 ϕ ( n ) = ϕ ( n p ) × p \phi(n) = \phi (\dfrac{n}{p}) \times p ϕ(n)=ϕ(pn)×p。相当于在 ϕ ( n p ) \phi (\dfrac{n}{p}) ϕ(pn) 中的某个 p i k − 1 p_i^{k - 1} pik−1 中乘上一个$ p_i$,也就是 ϕ ( n ) = ϕ ( n p ) × p \phi(n) = \phi(\dfrac{n}{p}) \times p ϕ(n)=ϕ(pn)×p。
-
若 p p p 与 n p \dfrac{n}{p} pn 互质,且 p p p 为质数,则 ϕ ( n ) = ϕ ( n p ) × ( p − 1 ) \phi(n) = \phi(\frac{n}{p}) \times(p - 1) ϕ(n)=ϕ(pn)×(p−1)。
∵ p 与 n p 互质,所以为积性函数 ∴ ϕ ( n ) = ϕ ( n p ) × ϕ ( p ) ∵ p 为质数 ∴ ϕ ( p ) = p − 1 ∴ ϕ ( n ) = ϕ ( n p ) × ( p − 1 ) \because p\ 与 \ \frac{n}{p}\ 互质,所以为积性函数\\ \therefore \phi(n) = \phi(\dfrac{n}{p}) \times \phi(p)\\ \because p\ 为质数\\ \therefore \phi(p) = p - 1\\ \therefore \phi(n) = \phi(\dfrac{n}{p}) \times (p - 1) ∵p 与 pn 互质,所以为积性函数∴ϕ(n)=ϕ(pn)×ϕ(p)∵p 为质数∴ϕ(p)=p−1∴ϕ(n)=ϕ(pn)×(p−1) -
求证: ∑ d ∣ n ϕ ( d ) = n \sum_{d \mid n} \phi(d) = n ∑d∣nϕ(d)=n。
证明:设 f ( n ) = ∑ d ∣ n ϕ ( d ) 。 若 m , n 互质,则 m , n 之间无公共因子,由乘法原理可知: f ( m n ) = ∑ d ∣ m n ϕ ( d ) = ( ∑ d ∣ n ϕ ( d ) ) × ( ∑ d ∣ m ϕ ( d ) ) = f ( n ) × f ( m ) ∴ f ( n ) 为积性函数 ∴ f ( n ) = ∏ i = 1 k f ( p i c i ) ,其中 p i , c i , k 都是相当于对 n 进行质因数分解得到的参数 ∵ 对于一个质因数分解的结果 p i c i ∴ f ( p i c i ) = ∑ d ∣ p i c i ϕ ( d ) = ϕ ( 1 ) + ϕ ( p i ) + ϕ ( p i 2 ) + ⋯ + ϕ ( p i c i ) ∵ 对于一个质数 p 的 k 次幂 n ,有 ϕ ( n ) = ( p − 1 ) × p k − 1 ∴ f ( p i c i ) = 1 + ( p i − 1 ) × ( p i 0 + p i 1 + ⋯ + p i c i − 1 ) = 1 + ( p i − 1 ) × 1 × ( 1 − p i c i ) 1 − p i = 1 + ( p i c i − 1 ) = p i c i ∴ f ( n ) = ∏ i = 1 k f ( p i c i ) = n 证明:设\ f(n) = \sum_{d \mid n} \phi(d)。\\ 若\ m,n\ 互质,则\ m,n\ 之间无公共因子,由乘法原理可知:\\ f(mn) = \sum_{d \mid mn} \phi(d) = (\sum_{d \mid n} \phi(d)) \times (\sum_{d \mid m} \phi(d)) = f(n) \times f(m)\\ \therefore f(n)\ 为积性函数\\ \therefore f(n) = \prod_{i = 1}^{k} f(p_i^{c_i}),其中\ p_i,c_i,k\ 都是相当于对\ n\ 进行质因数分解得到的参数\\ \because 对于一个质因数分解的结果\ p_i^{c_i}\\ \therefore f(p_i^{c_i}) = \sum_{d \mid p_i^{c_i}} \phi(d) = \phi(1) + \phi(p_i) + \phi(p_i^2) + \cdots + \phi(p_i^{c_i})\\ \because 对于一个质数\ p\ 的\ k\ 次幂\ n,有\ \phi(n) = (p - 1) \times p^{k - 1}\\ \therefore f(p_i^{c_i}) = 1 + (p_i - 1) \times (p_i^0 + p_i^1 + \cdots + p_i^{c_i - 1})\\ = 1 + (p_i - 1) \times \dfrac{1 \times (1 - p_i^{c_i})}{1 - p_i} = 1 + (p_i^{c_i} - 1) = p_i^{c_i}\\ \therefore f(n) = \prod_{i = 1}^{k} f(p_i^{c_i}) = n 证明:设 f(n)=d∣n∑ϕ(d)。若 m,n 互质,则 m,n 之间无公共因子,由乘法原理可知:f(mn)=d∣mn∑ϕ(d)=(d∣n∑ϕ(d))×(d∣m∑ϕ(d))=f(n)×f(m)∴f(n) 为积性函数∴f(n)=i=1∏kf(pici),其中 pi,ci,k 都是相当于对 n 进行质因数分解得到的参数∵对于一个质因数分解的结果 pici∴f(pici)=d∣pici∑ϕ(d)=ϕ(1)+ϕ(pi)+ϕ(pi2)+⋯+ϕ(pici)∵对于一个质数 p 的 k 次幂 n,有 ϕ(n)=(p−1)×pk−1∴f(pici)=1+(pi−1)×(pi0+pi1+⋯+pici−1)=1+(pi−1)×1−pi1×(1−pici)=1+(pici−1)=pici∴f(n)=i=1∏kf(pici)=n -
求证小于 n n n 且与 n n n 互质的数的和为 n × ϕ ( n ) 2 \dfrac{n \times \phi(n)}{2} 2n×ϕ(n)。
假设与 n 互质的数构成集合 A = { a 1 , a 2 , ⋯ , a m } ,显然由定义知 ϕ ( n ) = m 先证明 B = { n − a 1 , n − a 2 , ⋯ , n − a m } 之中的元素也与 n 互质 即若 x < n , gcd ( x , n ) = 1 ,求证 gcd ( n − x , n ) = 1 假设 gcd ( n − x , n ) ≠ 1 。设 n − x = k 1 g , n = k 2 g ( g > 1 ) 那么有 k 2 g − x = k 1 g , x = ( k 2 − k 1 ) g ,则易知 gcd ( n , x ) = g ,与条件矛盾 故有 gcd ( n − x , n ) = 1 发现 A = B ∴ 为 1 2 [ ( a 1 + a 2 + ⋯ + a m + ( n − a 1 ) + ( n − a 2 ) + ⋯ + ( n − a m ) ] × m 即为 n × ϕ ( n ) 2 假设与\ n\ 互质的数构成集合\ A = \{a_1,a_2,\cdots,a_m\},显然由定义知\ \phi(n) = m\\ 先证明\ B = \{n - a_1,n - a_2,\cdots,n - a_m\} \ 之中的元素也与\ n \ 互质\\ 即若\ x < n,\gcd (x,n) = 1,求证\ \gcd (n - x,n) = 1\\ 假设\ \gcd (n - x,n) ≠ 1。设\ n - x = k_1g,n = k_2g\ (g > 1)\\ 那么有\ k_2g - x = k_1g,x = (k_2 - k_1)g,则易知\ \gcd (n,x) = g,与条件矛盾\\ 故有\ \gcd (n - x,n) = 1\\ 发现\ A = B\\ \therefore 为\ \frac{1}{2}[(a_1 + a_2 + \cdots + a_m + (n - a_1) + (n - a_2) + \cdots + (n - a_m)] \times m\\ 即为\ \frac{n \times \phi(n)}{2} 假设与 n 互质的数构成集合 A={a1,a2,⋯,am},显然由定义知 ϕ(n)=m先证明 B={n−a1,n−a2,⋯,n−am} 之中的元素也与 n 互质即若 x<n,gcd(x,n)=1,求证 gcd(n−x,n)=1假设 gcd(n−x,n)=1。设 n−x=k1g,n=k2g (g>1)那么有 k2g−x=k1g,x=(k2−k1)g,则易知 gcd(n,x)=g,与条件矛盾故有 gcd(n−x,n)=1发现 A=B∴为 21[(a1+a2+⋯+am+(n−a1)+(n−a2)+⋯+(n−am)]×m即为 2n×ϕ(n)
5. 代码
-
根据欧拉函数通式求解。
void work (int n) { phi[1] = 1; for (int i = 2;i <= n;++i) phi[i] = i;//先标记为自己,方便标记质数,也方便为公式法求解 for (int i = 2;i <= n;++i) { if (phi[i] == i)//为素数 for (int j = i;j <= n;j += i) phi[j] = phi[j] / i * (i - 1);//其中的一个 (pi - 1) / pi } } -
根据线性筛实现 O ( n ) O(n) O(n) 的时间复杂度求解。
void work (int n) { phi[1] = 1; for (int i = 2;i <= n;++i) { if (!flag[i]) { p[++cnt] = i; phi[i] = i - 1;//素数 p 的欧拉函数为 p - 1 } for (int j = 1;j <= cnt;++j) { if (i * p[j] > n) break; flag[i * p[j]] = 1; if (i % p[j] == 0) { phi[i * p[j]] = phi[i] * p[j];//若 p 能整除 n / p,则 φ (n) = φ (n / p) * p break; } phi[i * p[j]] = phi[i] * (p[j] - 1);//若 p 与 n / p 互质,且 p 为质数,则 φ (n) = φ (n / p) * (p - 1) } } } -
利用性质 f f f 的求解。
void work (int n) { for (int i = 1;i <= n;++i) phi[i] = i; for (int i = 1;i <= n;++i) for (int j = i + i;j <= n;j += i) phi[j] -= phi[i];//减去自己所有因子的值即为 φ(i) }
欧拉定理
如果 a , n a,n a,n 为正整数,且 gcd ( a , n ) = 1 \gcd (a,n) = 1 gcd(a,n)=1,则 a ϕ ( n ) ≡ 1 ( m o d n ) a^ {\phi(n)} ≡ 1 \pmod n aϕ(n)≡1(modn)。
已知 a , n ∈ N + a,n \in \N_{+} a,n∈N+,且 gcd ( a , n ) = 1 \gcd (a,n) = 1 gcd(a,n)=1。求证 a ϕ ( n ) ≡ 1 ( m o d n ) a^{\phi(n)} \equiv 1 \pmod n aϕ(n)≡1(modn)。
证明:令集合 A = { x 1 , x 2 , ⋯ , x ϕ ( n ) } 来表示所有不大于 n 且与其互质的数 再令集合 B = { a x 1 m o d n , a x 2 m o d n , ⋯ , a x ϕ n m o d n } ∵ gcd ( a , n ) = 1 , gcd ( x i , n ) = 1 ∴ gcd ( a x i , n ) = 1 由欧几里得算法可知 gcd ( a x i m o d n , n ) = 1 假设 B 集合中的存在相同元素,即 a x 1 = k 1 n + b , a x 2 = k 2 n + b ( 0 < x 1 , x 2 < n 且 gcd ( a , n ) = 1 ) 则有 a ( x 1 − x 2 ) = ( k 1 − k 2 ) b ∵ gcd ( a , n ) = 1 ∴ x 1 − x 2 = n , k 1 − k 2 = a ∵ 0 < x 1 , x 2 < n ∴ x 1 − x 2 = n 不成立,与假设矛盾,故 B 集合中元素互不相同 ∴ A = B ∴ a ϕ ( n ) × ∏ i = 1 ϕ ( n ) x i ≡ ∏ i = 1 ϕ ( n ) a × x i ≡ ∏ i = 1 ϕ ( n ) x i ( m o d n ) ∴ a ϕ ( n ) ≡ 1 ( m o d n ) 证明:令集合\ A = \{x_1,x_2,\cdots,x_{\phi(n)}\}\ 来表示所有不大于\ n\ 且与其互质的数\\再令集合\ B = \{ax_1 \bmod n,ax_2 \bmod n,\cdots,ax_{\phi{n}} \bmod n\}\\\because \gcd (a,n) = 1,\gcd (x_i,n) = 1\\\therefore \gcd (ax_i,n) = 1\\由欧几里得算法可知\ \gcd (ax_i \bmod n,n) = 1\\\\假设\ B\ 集合中的存在相同元素,即\ ax_1 = k_1n + b,ax_2 = k_2n + b\ (0 < x_1,x_2 < n\ 且\ \gcd(a,n) = 1)\\则有\ a(x_1 - x_2) = (k_1 - k_2)b\\\because \gcd (a,n) = 1\\\therefore x_1 - x_2 = n,k_1 - k_2 = a\\\because 0 < x_1,x_2 < n\\\therefore x_1 - x_2 = n\ 不成立,与假设矛盾,故\ B\ 集合中元素互不相同\\\\\therefore A = B\\\therefore a^{\phi(n)}\times \prod_{i = 1}^{\phi(n)} x_i \equiv \prod_{i = 1}^{\phi(n)} a \times x_i \equiv \prod_{i = 1}^{\phi(n)} x_i \pmod n\\\\\therefore a^{\phi(n)} \equiv 1 \pmod n 证明:令集合 A={x1,x2,⋯,xϕ(n)} 来表示所有不大于 n 且与其互质的数再令集合 B={ax1modn,ax2modn,⋯,axϕnmodn}∵gcd(a,n)=1,gcd(xi,n)=1∴gcd(axi,n)=1由欧几里得算法可知 gcd(aximodn,n)=1假设 B 集合中的存在相同元素,即 ax1=k1n+b,ax2=k2n+b (0<x1,x2<n 且 gcd(a,n)=1)则有 a(x1−x2)=(k1−k2)b∵gcd(a,n)=1∴x1−x2=n,k1−k2=a∵0<x1,x2<n∴x1−x2=n 不成立,与假设矛盾,故 B 集合中元素互不相同∴A=B∴aϕ(n)×i=1∏ϕ(n)xi≡i=1∏ϕ(n)a×xi≡i=1∏ϕ(n)xi(modn)∴aϕ(n)≡1(modn)
乘法逆元
1. 费马小定理
欧拉定理的特殊情况,当
n
n
n 为质数时:
∵
ϕ
(
n
)
=
n
−
1
∴
a
ϕ
(
n
)
=
a
n
−
1
≡
1
m
o
d
n
\because \phi(n) = n - 1\\ \therefore a^{\phi(n)} = a^{n - 1} \equiv 1 \mod n
∵ϕ(n)=n−1∴aϕ(n)=an−1≡1modn
2. 计算
a
÷
b
%
c
a \div b \% c
a÷b%c 时,假设存在
p
×
b
≡
1
(
m
o
d
c
)
p \times b ≡ 1 \pmod c
p×b≡1(modc),则
p
p
p 为
b
b
b 的逆元。
a
÷
b
%
c
=
a
×
p
%
c
a \div b \% c = a \times p \% c
a÷b%c=a×p%c。
a
÷
b
=
k
×
c
+
r
a
=
k
×
b
×
c
+
b
×
r
∵
p
×
b
≡
1
(
m
o
d
c
)
∴
a
×
p
≡
k
×
c
+
r
(
m
o
d
c
)
∴
p
×
b
+
k
×
c
=
1
a \div b = k \times c + r\\ a = k \times b \times c + b \times r\\ \because p \times b \equiv 1 \pmod c\\ \therefore a \times p \equiv k \times c + r \pmod c\\ \therefore p \times b + k \times c = 1
a÷b=k×c+ra=k×b×c+b×r∵p×b≡1(modc)∴a×p≡k×c+r(modc)∴p×b+k×c=1
相当于
b
,
c
b,c
b,c 已知,则可以通过扩展欧几里得算法求逆元,但需要
gcd
(
b
,
c
)
=
1
\gcd (b,c) = 1
gcd(b,c)=1 时才有解。时间复杂度
O
(
n
log
n
)
O(n \log n)
O(nlogn)。
int inv (int b,int c)
{
int x,y;
exgcd (b,c,x,y);
return (x % c + c) % c;//化成正数
}
当
c
c
c 为质数时,逆元可以表示为
b
c
−
2
%
c
b^{c - 2} \% c
bc−2%c,直接可以使用快速幂求解。
∵
c
为质数
∴
gcd
(
b
,
c
)
=
1
∴
b
ϕ
(
c
)
m
o
d
c
=
1
∴
b
×
b
ϕ
(
c
)
−
1
=
1
则逆元
p
=
b
ϕ
(
c
)
−
1
=
b
c
−
1
−
1
=
b
c
−
2
\because c \ 为质数\\ \therefore \gcd (b,c) = 1\\ \therefore b^{\phi(c)} \bmod c = 1\\ \therefore b \times b^{\phi(c) - 1} = 1\\ 则逆元\ p= b^{\phi(c) - 1} = b^{c - 1 - 1} = b^{c - 2}
∵c 为质数∴gcd(b,c)=1∴bϕ(c)modc=1∴b×bϕ(c)−1=1则逆元 p=bϕ(c)−1=bc−1−1=bc−2
3. 线性求逆元
时间复杂度为
O
(
n
)
O(n)
O(n)。
令
p
是质数,则有
:
i
n
v
i
=
(
p
−
p
i
)
×
i
n
v
p
%
i
m
o
d
p
。
令
t
=
p
i
,
k
=
p
%
i
,则:
t
×
i
+
k
≡
0
(
m
o
d
p
)
−
t
×
i
≡
k
(
m
o
d
p
)
同时除以
i
×
k
得:
−
t
×
i
n
v
k
≡
i
n
t
v
i
(
m
o
d
p
)
令\ p\ 是质数,则有:\ inv_i = (p - \dfrac{p}{i}) \times inv_{p \% i} \bmod p。\\ \\ 令\ t = \dfrac{p}{i},k = p \% i,则:\\ t \times i + k \equiv 0 \pmod p\\ -t \times i \equiv k \pmod p\\ 同时除以\ i \times k\ 得:\\ -t \times inv_k \equiv intv_i \pmod p
令 p 是质数,则有: invi=(p−ip)×invp%imodp。令 t=ip,k=p%i,则:t×i+k≡0(modp)−t×i≡k(modp)同时除以 i×k 得:−t×invk≡intvi(modp)
void init (int n,int mod)
{
inv[1] = 1;
for (int i = 2;i <= n;++i) inv[i] = (p - p / i) * inv[p % i] % p;
}
4. 无法求逆元的转化
a b m o d m = a m o d ( b × m ) b a b = k × m + x ( x < m ) a = k × b × m + b × x a m o d ( b × m ) = b × x a m o d ( b × m ) b = x \dfrac{a}{b} \bmod m = \dfrac{a \bmod (b \times m)}{b}\\ \\ \dfrac{a}{b} = k \times m + x\ (x < m)\\ a = k \times b \times m + b \times x\\ a \bmod (b \times m) = b \times x\\ \frac{a \bmod (b \times m)}{b} = x bamodm=bamod(b×m)ba=k×m+x (x<m)a=k×b×m+b×xamod(b×m)=b×xbamod(b×m)=x
中国剩余定理
求解以下方程:
∀
m
i
∣
1
≤
i
≤
n
,
gcd
(
m
i
,
m
i
+
j
)
=
1
(
1
≤
j
≤
n
−
i
)
{
x
≡
a
1
(
m
o
d
m
1
)
x
≡
a
2
(
m
o
d
m
2
)
⋯
x
≡
a
n
(
m
o
d
m
n
)
\forall m_{i \mid 1 \le i \le n},\gcd (m_i,m_{i + j}) = 1\ (1 \le j \le n - i)\\\begin{cases}x \equiv a_1 \pmod {m_1}\\x \equiv a_2 \pmod {m_2}\\\cdots\\x \equiv a_n \pmod {m_n}\\\end{cases}
∀mi∣1≤i≤n,gcd(mi,mi+j)=1 (1≤j≤n−i)⎩
⎨
⎧x≡a1(modm1)x≡a2(modm2)⋯x≡an(modmn)
构造答案,设
M
=
∏
i
=
1
n
m
i
,
M
i
=
M
m
i
s
i
:
M
i
×
s
i
≡
1
(
m
o
d
m
i
)
∵
M
i
=
M
m
i
∴
M
i
×
s
i
m
o
d
m
j
=
0
(
1
≤
j
≤
n
,
j
≠
i
)
x
=
∑
i
=
1
n
a
i
×
M
i
×
s
i
通解为
x
+
k
×
M
\begin{aligned}M &= \prod_{i = 1}^n m_i, \quad M_i = \frac{M}{m_i} \\s_i &: \; M_i \times s_i \equiv 1 \pmod {m_i} \\\because &\; M_i = \frac{M}{m_i} \\\therefore &\; M_i \times s_i \bmod m_j = 0 \quad (1 \le j \le n,\ j \ne i) \\x &= \sum_{i = 1}^n a_i \times M_i \times s_i \\\text{通解为} &\; x + k \times M\end{aligned}
Msi∵∴x通解为=i=1∏nmi,Mi=miM:Mi×si≡1(modmi)Mi=miMMi×simodmj=0(1≤j≤n, j=i)=i=1∑nai×Mi×six+k×M
所以直接通过
n
n
n 次
exgcd
\texttt{exgcd}
exgcd 求出
s
i
s_i
si,最后合并即可。
ll CRT (int n,int a[],int m[])
{
ll M = 1,ans = 0;
for (int i = 1;i <= n;++i) M *= m[i];
for (int i = 1;i <= n;++i)
{
ll x = 0,y = 0;
exgcd (M / m[i],m[i],x,y);
x = (x % m[i] + m[i]) % m[i];
ans += M / m[i] * x * a[i];
ans %= M;
}
return ans;
}
整除分块
求下列式子的值。
∑ i = 1 n ⌊ n i ⌋ ( 1 ≤ n ≤ 1 0 9 ) \sum _{i = 1} ^ n \lfloor\dfrac{n}{i}\rfloor \ (1 \le n \le 10^9) i=1∑n⌊in⌋ (1≤n≤109)
若用朴素的算法,时间复杂度为
O
(
n
)
O(n)
O(n),显然会
TLE
\texttt{TLE}
TLE。那么再给出一种
O
(
n
)
O(\sqrt n)
O(n) 的做法。
先给出所有的
⌊
n
i
⌋
\lfloor\dfrac{n}{i}\rfloor
⌊in⌋ 的取值不会超过
n
\sqrt{n}
n 种的证明:
当 i ≤ n 时,显然取值不超过 n ; 当 i > n 时, ⌊ n i ⌋ < n ,故取值不超过 n 。 综上,命题成立。 当 \ i \le \sqrt{n} 时,显然取值不超过 \sqrt{n};\\ 当 i > \sqrt{n} 时,\lfloor\dfrac{n}{i}\rfloor < \sqrt{n},故取值不超过 \sqrt{n}。\\ 综上,命题成立。 当 i≤n时,显然取值不超过n;当i>n时,⌊in⌋<n,故取值不超过n。综上,命题成立。
设一段取值均为 ⌊ n i ⌋ \lfloor\dfrac{n}{i}\rfloor ⌊in⌋ 的区间的左、右端点分别为 L , R L,R L,R。
∵ ⌊ n R ⌋ ≤ n R ∴ R ≤ n ⌊ n L ⌋ ∴ R max = ⌊ n ⌊ n L ⌋ ⌋ \because \lfloor\dfrac{n}{R}\rfloor \le \frac{n}{R}\\\therefore R \le \dfrac{n}{\lfloor\dfrac{n}{L}\rfloor}\\\therefore R_{\max} = \biggl\lfloor{\dfrac{n}{\lfloor{\dfrac{n}{L}\rfloor}}\biggr\rfloor} ∵⌊Rn⌋≤Rn∴R≤⌊Ln⌋n∴Rmax=⌊⌊Ln⌋n⌋
代码如下:
for (int L = 1,R;L <= n;L = R + 1)
{
R = n / (n / L);
ans += 1ll * (R - L * 1) * (n / L);
}
组合数学基础
1. 组合数的两种表示方法
对于递推公式,是对于第 n n n 项是否选择得出的。
( n m ) = C n m = n × ( n − 1 ) × ( n − 2 ) ⋯ × ( n − m + 1 ) m ! = n ! m ! ( n − m ) ! ( n m ) = ( n − 1 m − 1 ) + ( n − 1 m ) \tbinom{n}{m} = C^m_n = \dfrac{n \times (n - 1) \times (n - 2) \cdots \times (n - m + 1)} {m!} = \dfrac{n!}{m!(n - m)!}\\\tbinom{n}{m} = \tbinom{n - 1}{m - 1} + \tbinom{n - 1}{m} (mn)=Cnm=m!n×(n−1)×(n−2)⋯×(n−m+1)=m!(n−m)!n!(mn)=(m−1n−1)+(mn−1)
2. 组合数的预处理
void init ()
{
c[0][0] = 1;
for (int i = 1;i < n;++i)
{
c[i][i] = c[i][0] = 1;
for (int j = 1;j < i;++j)
{
c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
c[i][j] %= MOD;
}
}
}
3. 组合数的变形
( 1 ) k × ( n k ) = k × n ! k ! ( n − k ) ! = k × n × ( n − 1 ) ! k ! ( n − k ) ! = n × ( n − 1 ) ! ( k − 1 ) ! ( n − 1 − ( k − 1 ) ) ! = n × ( n − 1 k − 1 ) ( 2 ) ∑ i = 1 n i × ( n i ) = ∑ i = 1 n n × ( n − 1 i − 1 ) = n × 2 n − 1 ( 3 ) ∑ i = 1 n i 2 × ( n i ) = n × ( n + 1 ) × 2 n − 2 ( 4 ) ∑ i = 0 n ( n i ) 2 = ( 2 n n ) (1)\ k \times \tbinom{n}{k} = k \times \dfrac{n!}{k!(n - k)!}\\= k \times n \times \dfrac{(n - 1)!}{k!(n - k)!} = n \times \dfrac{(n - 1)!}{(k - 1)!(n - 1 - (k - 1))!} = n \times \tbinom{n - 1}{k - 1}\\ (2)\ \sum_{i = 1}^{n}i \times \tbinom{n}{i} = \sum_{i = 1}^{n} n \times \tbinom{n - 1}{i - 1} = n \times 2^{n - 1}\\(3)\ \sum_{i = 1}^{n} i^2 \times \tbinom{n}{i} = n \times (n + 1) \times 2^{n - 2}\\(4)\ \sum_{i = 0}^{n} \tbinom{n}{i}^2 = \tbinom{2n}{n} (1) k×(kn)=k×k!(n−k)!n!=k×n×k!(n−k)!(n−1)!=n×(k−1)!(n−1−(k−1))!(n−1)!=n×(k−1n−1)(2) i=1∑ni×(in)=i=1∑nn×(i−1n−1)=n×2n−1(3) i=1∑ni2×(in)=n×(n+1)×2n−2(4) i=0∑n(in)2=(n2n)
其中的 ( 3 ) (3) (3)可以转化为模型。等号左边为班级中的 n n n 个人选择候选人,然后从候选人中选一个班长与副班长,同一个人可以身兼两职,求最终方案数;等号右边为身兼两职与两个人分别当选的两种情况,有加法原理相加得到,即:
n × 2 n − 1 + n × ( n − 1 ) × 2 n − 2 = n × ( n + 1 ) × 2 n − 2 n \times 2^{n - 1} + n \times (n - 1) \times 2^{n - 2} = n \times (n + 1) \times 2^{n - 2} n×2n−1+n×(n−1)×2n−2=n×(n+1)×2n−2
(
4
)
(4)
(4) 也一样可以转化为模型。等号右边为班级中有
n
n
n 个男生和
n
n
n 个女生,从中选
n
n
n 人;等号左边相当于等价的,男生选
i
i
i 个,女生选
n
−
i
n - i
n−i 个,则有
:
∑
i
=
0
n
(
n
i
)
×
(
n
n
−
i
)
=
∑
i
=
0
n
(
n
i
)
2
\sum_{i = 0}^{n} \tbinom{n}{i} \times \tbinom{n}{n - i} = \sum_{i = 0}^{n} \tbinom{n}{i}^2
i=0∑n(in)×(n−in)=i=0∑n(in)2
【摘自 CF2077C Binary Subsequence Value Sum题解】
证明 ∑ i = 0 n C n i i = n 2 n − 1 \sum_{i=0}^nC_n^ii=n2^{n-1} ∑i=0nCnii=n2n−1
i = C i 1 i=C_i^1 i=Ci1,则原式等于 ∑ i = 0 n C n i C i 1 \sum_{i=0}^nC_n^iC_i^1 ∑i=0nCniCi1,考虑其组合意义,即先从 n n n 个元素中选若干个,再从若干个元素里选出一个的方案数。那我们先选这一个,有 n n n 种方案,再从剩下 n − 1 n-1 n−1 个元素中选出若干个,有 2 n − 1 2^{n-1} 2n−1 种方案,所以是 n 2 n − 1 n2^{n-1} n2n−1。证明 ∑ i = 0 n C n i i 2 = n ( n + 1 ) 2 n − 2 \sum_{i=0}^nC_n^ii^2=n(n+1)2^{n-2} ∑i=0nCnii2=n(n+1)2n−2
考虑 i 2 = i + i ( i − 1 ) = i + 2 × i ( i − 1 ) 2 = C i 1 + 2 C i 2 i^2=i+i(i-1)=i+2\times\frac{i(i-1)}{2}=C_i^1+2C_i^2 i2=i+i(i−1)=i+2×2i(i−1)=Ci1+2Ci2,则原式等于 ∑ i = 0 n C n i C i 1 + 2 C n i C i 2 \sum_{i=0}^nC_n^iC_i^1+2C_n^iC_i^2 ∑i=0nCniCi1+2CniCi2,等于 n 2 n − 1 + 2 ∑ i = 0 n C n i C i 2 n2^{n-1}+2\sum_{i=0}^nC_n^iC_i^2 n2n−1+2∑i=0nCniCi2,则我们只需解决 ∑ i = 0 n C n i C i 2 \sum_{i=0}^nC_n^iC_i^2 ∑i=0nCniCi2。
考虑组合意义,即从 n n n 个元素里选出若干个,再从若干个元素里选出两个的方案数。那我们先选出这两个,有 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n−1) 种方案,然后再从剩下的元素中选出若干个,有 2 n − 2 2^{n-2} 2n−2 种方案,所以有 n ( n − 1 ) 2 n − 3 n(n-1)2^{n-3} n(n−1)2n−3 种方案。
二项式定理
1. 概念
对于每一个 x + y x + y x+y 的选择,则选 i i i 个 x x x,剩余均选择 y y y 时,答案为:
C n i x i y n − i ( 1 ≤ n ≤ i ) C^i_n x^i y^{n - i} \ (1 \le n \le i) Cnixiyn−i (1≤n≤i)
因此有:
( x + y ) n = C n 0 x n y 0 + C n 1 x y − 1 y + C n 2 x n − 2 y 2 + ⋯ + C n n x 0 y n = ∑ k = 0 n ( n k ) x n − k y k (x + y)^n = C_n^0 x^n y^0 + C^1_n x^{y - 1} y + C^2_n x^{n - 2} y^2 + \cdots + C^n_n x^0 y^n\\= \sum_{k = 0}^n \tbinom{n}{k} x^{n - k}y^k (x+y)n=Cn0xny0+Cn1xy−1y+Cn2xn−2y2+⋯+Cnnx0yn=k=0∑n(kn)xn−kyk
2. 二项式定理的变形
( 1 ) ( x + y ) n = ∑ k = 0 n ( n n − k ) x n − k y k ( 2 ) ( x + y ) n = ∑ k = 0 n ( n n − k ) x k y n − k ( 3 ) ( x + y ) n = ∑ k = 0 n ( n k ) x k y n − k ( 4 ) 当 y = 1 时, ( 1 + x ) n = ∑ k = 0 n ( n k ) x k = ∑ k = 0 n ( n n − k ) x k ( 5 ) 当 x = 2 , y = 1 时, ( x + y ) n = ∑ i = 0 n ( n i ) 2 i = 3 n ( 6 ) 当 x = y = 1 时, ( x − y ) n = ∑ i = 0 n ( n i ) 2 i × ( − 1 ) i = 0 ( 7 ) 当 x = y = 1 时, ( x + y ) n = ∑ i = 0 n ( n i ) = 2 n ( 8 ) ( n 0 ) + ( n 2 ) + ⋯ = ( n 1 ) + ( n 3 ) + ⋯ = 2 n − 1 (1)\ (x + y)^n = \sum_{k = 0}^n \tbinom{n}{n - k} x^{n - k}y^k\\ (2)\ (x + y)^n = \sum_{k = 0}^n \tbinom{n}{n - k} x^k y^{n - k}\\ (3)\ (x + y)^n = \sum_{k = 0}^n \tbinom{n}{k} x^k y^{n - k}\\ (4)\ 当\ y = 1\ 时,(1 + x)^n = \sum_{k = 0}^n \tbinom{n}{k} x^k = \sum_{k = 0}^n \tbinom{n}{n - k} x^k\\ (5)\ 当\ x = 2,y = 1\ 时,(x + y)^n = \sum_{i = 0}^{n} \tbinom{n}{i}2^i = 3^n\\ (6)\ 当\ x = y = 1\ 时,(x - y)^n = \sum_{i = 0}^{n} \tbinom{n}{i}2^i \times (-1)^i= 0\\ (7)\ 当\ x = y = 1\ 时,(x + y)^n = \sum_{i = 0}^{n} \tbinom{n}{i} = 2^n\\ (8)\ \tbinom{n}{0} + \tbinom{n}{2} + \cdots = \tbinom{n}{1} + \tbinom{n}{3} + \cdots = 2^{n - 1} (1) (x+y)n=k=0∑n(n−kn)xn−kyk(2) (x+y)n=k=0∑n(n−kn)xkyn−k(3) (x+y)n=k=0∑n(kn)xkyn−k(4) 当 y=1 时,(1+x)n=k=0∑n(kn)xk=k=0∑n(n−kn)xk(5) 当 x=2,y=1 时,(x+y)n=i=0∑n(in)2i=3n(6) 当 x=y=1 时,(x−y)n=i=0∑n(in)2i×(−1)i=0(7) 当 x=y=1 时,(x+y)n=i=0∑n(in)=2n(8) (0n)+(2n)+⋯=(1n)+(3n)+⋯=2n−1
隔板法
1. 题意
把 n n n 个相同的小球,放到 m m m 个不同的盒子中,盒子不能为空,求方案数。或者求 x 1 + x 2 + ⋯ + x m = n x_1 + x_2 + \cdots + x_m = n x1+x2+⋯+xm=n 的正整数解。
解法 相当于在
n
−
1
n - 1
n−1 个间隔中选择
m
−
1
m - 1
m−1 个间隔,将其分为
m
m
m 份。故为:
(
n
−
1
m
−
1
)
\tbinom{n - 1}{m - 1}
(m−1n−1)
2. 变式
把 n n n 个相同的小球,放到 m m m 个不同的盒子中,盒子可以为空,求方案数。或者求 x 1 + x 2 + ⋯ + x m = n x_1 + x_2 + \cdots + x_m = n x1+x2+⋯+xm=n 的非负整数解。
解法 相当于在先在每个盒子中放入
1
1
1 个球,然后求
n
+
m
n + m
n+m 个相同的小球放入
m
m
m 个不同的盒子的方案数,盒子不能为空。故为:
(
n
+
m
−
1
m
−
1
)
\tbinom{n + m - 1}{m - 1}
(m−1n+m−1)
错位排列
∀ i ∣ 1 ≤ i ≤ n , f i ! = i \forall i \mid 1 \le i \le n,f_i != i ∀i∣1≤i≤n,fi!=i
递推公式为:
f
1
=
0
f
2
=
1
f
i
=
(
i
−
1
)
×
(
f
i
−
1
+
f
i
−
2
)
(
i
>
2
)
f_1 = 0\\f_2 = 1\\f_i = (i - 1) \times (f_{i - 1} + f_{i - 2})\ (i > 2)
f1=0f2=1fi=(i−1)×(fi−1+fi−2) (i>2)
对于第
i
i
i 项,可以在前
i
−
1
i - 1
i−1 个数中选一个数与第
i
i
i 个数替换,共
i
−
1
i - 1
i−1 中,然后问题变为求
(
i
−
1
)
×
(
f
i
−
2
)
(i - 1) \times (f_{i - 2})
(i−1)×(fi−2)。也可以将前
i
−
1
i - 1
i−1 个数中的一个数放在前 i - 1 个位置中符合条件的某一个位置,相当于求
(
i
−
1
)
×
f
i
−
1
(i - 1) \times f_{i - 1}
(i−1)×fi−1 这一新的错排。
圆排列
原来每组排列都有 n n n 种排列等价,故方案数为:
n ! n \frac{n!}{n} nn!
多重集合的排列
- 集合中有 k k k 种不同类型的对象,每种数量均为无限,从中选 n n n 个,排列的方案数为:
k n k^n kn
- 集合中有 k k k 种不同类型的对象,每种数量分别为 n 1 n_1 n1 至 n k n_k nk,从中选 n n n 个。相当于选出 n 1 n_1 n1 个位置放第 1 1 1 种,选出 n 2 n_2 n2 个位置放第 2 2 2 种,以此类推。方案数为:
( n n 1 ) × ( n − n 1 n 2 ) × ⋯ × ( n − n 1 − n 2 − ⋯ − n k − 1 n k ) = n ! n 1 ! n 2 ! ⋯ n k ! \tbinom{n}{n_1} \times \tbinom{n - n_1}{n_2} \times \cdots \times \tbinom{n - n_1 - n_2 - \cdots - n_{k - 1}}{n_k}= \dfrac{n!}{n_1!n_2!\cdots n_k!} (n1n)×(n2n−n1)×⋯×(nkn−n1−n2−⋯−nk−1)=n1!n2!⋯nk!n!
多重集合的组合
集合中有 k k k 种不同类型的对象,每种数量均为无限,从中选 n n n 个。等价于 k k k 个相同的球放到 n n n 个不同的盒子中,盒子可以为空。或者等价于选 k k k 次球,每次都可以选 n n n 种球,且选择不分先后。组合的方案数为:
( n + k − 1 k ) = ( n + k − 1 n − 1 ) \tbinom{n + k - 1}{k} = \tbinom{n + k - 1}{n - 1} (kn+k−1)=(n−1n+k−1)
康托展开
1. 计算排列的排名
设 a i a_i ai 表示 i i i 位置右边比它小的数的个数,则该排列之前的排列总数为:
x = a 1 ( n − 1 ) ! + a 2 ( n − 2 ) ! + ⋯ + a n 0 ! x = a_1 (n - 1)! + a_2 (n - 2)! + \cdots + a_n0! x=a1(n−1)!+a2(n−2)!+⋯+an0!
倘若 i i i 位置上的数比该数小,则在它右边的数可以随意放置,若 i i i 位置上的数等于该数,则继续判断 i + 1 i + 1 i+1 位置的数的情况,以此类推。因此可以由加法原理得可知该排列之前的排列总数。所以求排名的公式为:
a n s = 1 + ∑ i = 1 n a i × ( n − i ) ! ans = 1 + \sum_{i = 1}^n a_i \times (n - i)! ans=1+i=1∑nai×(n−i)!
2. 计算特定排名的排列
即康托展开的逆展开。
利用康托展开的公式,类似进制转换的方式去确定从高到底的每一位。若排列长度为 x x x,求编号为 0 0 0 开始的,编号为 k k k 的排列。方法如下: p = k ( x − 1 ) ! p = \frac{k}{(x - 1)!} p=(x−1)!k,则说明第一位右边有 p p p 个数比它小,所以最高位为 p + 1 p + 1 p+1,然后取余数重复操作,知道确定排列上的所有数字。
3. 求下一个排列
对于一个排列: a 1 , a 2 , ⋯ , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an。从后往前找到第一个 p i < p i + 1 p_i < p_{i + 1} pi<pi+1 的位置,从后往前找到第一个 p j < p i p_j < p_i pj<pi 的位置。最后交换 p i , p j p_i,p_j pi,pj 并颠倒 i i i 位置以后的所有元素即可。
斯特林数
1. 第一类斯特林数
求将 n n n 个不同的物体摆成k个非空环的方案数。采用动态规划的做法,对于第 i i i 个物体,可以任取一个环加入,也可以构造一个新环,故有 d p n , k = ( n − 1 ) d p n − 1 , k + d p n − 1 , k − 1 dp_{n,k} = (n - 1)dp_{n - 1,k} + dp_{n - 1,k - 1} dpn,k=(n−1)dpn−1,k+dpn−1,k−1。(当然有初始化 d p 0 , 0 = d p 1 , 1 = 1 dp_{0,0} = dp_{1,1} = 1 dp0,0=dp1,1=1)
2.第二类斯特林数
求将 n n n 个不同的物体分成 k k k 个非空集合的方案数。采用动态规划的做法,对于第 i i i 个物体,可以任取一个集合加入,也可以放入一个新集合中,故有 k × d p n − 1 , k + d p n − 1 , k − 1 k \times dp_{n - 1,k} + dp_{n - 1,k - 1} k×dpn−1,k+dpn−1,k−1。(当然有初始化 d p i , i = d p i , 1 = 1 dp_{i,i} = dp_{i,1} = 1 dpi,i=dpi,1=1)
卡特兰数
题目描述,假如有一个 n × n n\times n n×n 的网络,从左下角 A A A 点走到右上角 B B B 点且不穿越对角线的方案数。通过几何方法证明,答案为:
Catalan ( n ) = ( 2 n n ) − ( 2 n n + 1 ) = 1 n + 1 ( 2 n n ) = 1 n + 1 ∑ i = 0 n ( n i ) 2 \text{Catalan}(n)= \tbinom{2n}{n} - \tbinom{2n}{n + 1}= \frac{1}{n + 1}\tbinom{2n}{n}= \frac{1}{n + 1}\sum_{i = 0}^{n}\tbinom{n}{i}^2 Catalan(n)=(n2n)−(n+12n)=n+11(n2n)=n+11i=0∑n(in)2
其它的表达形式还有:
C ( n + 1 ) = ∑ i = 0 n C ( i ) × C ( n − i ) , C ( 0 ) = 1 C ( n + 1 ) = 2 ( 2 n + 1 ) n + 2 C ( n ) , C ( 0 ) = 1 C(n + 1) = \sum_{i = 0}^n C(i)\times C(n - i),C(0) = 1\\C(n + 1) = \frac{2(2n + 1)}{n + 2} C(n),C(0) = 1 C(n+1)=i=0∑nC(i)×C(n−i),C(0)=1C(n+1)=n+22(2n+1)C(n),C(0)=1
常见应用:
- 合法的括号匹配
- n n n 个节点二叉树的形态数
- 入栈出栈的排列总数
- 凸 n + 2 n+2 n+2 边形的分割
放球问题
设 d p i , j dp_{i,j} dpi,j 表示 i i i 个小球放到 j j j 个盒子的方案数。
1. 球相同,盒相同,可为空。
则有: d p i , j = d p i , j − 1 + d p i − 1 , j dp_{i,j} = dp_{i,j - 1} + dp_{i - 1,j} dpi,j=dpi,j−1+dpi−1,j。
2. 球相同,盒相同,不可为空。
则有: d p i , j = d p i − j , j dp_{i,j} = dp_{i - j,j} dpi,j=dpi−j,j。
3. 球不同,盒不同,可为空。
则有: j i j^i ji。
4. 球不同,盒相同,不可为空。
则有: d p i , j = d p i − 1 , j + d p i − 1 , j − 1 dp_{i,j} = dp_{i - 1,j} + dp_{i - 1,j - 1} dpi,j=dpi−1,j+dpi−1,j−1。
5. 球不同,盒不同,不可为空。
则有: d p i , j × j ! dp_{i,j} \times {j!} dpi,j×j!。
6. 球不同,盒相同,可为空。
枚举盒子数,则有: d p i , j = d p i − 1 , j + d p i − 1 , j − 1 dp_{i,j} = dp_{i - 1,j} + dp_{i - 1,j - 1} dpi,j=dpi−1,j+dpi−1,j−1。
7. 球相同,盒不同,不可为空。
隔板法,则有: ( i − 1 j − 1 ) \tbinom{i - 1}{j - 1} (j−1i−1)。
8. 球相同,盒不同,可为空。
则有: ( i + j − 1 j − 1 ) \tbinom{i + j - 1}{j - 1} (j−1i+j−1)。
卢卡斯定理
n = ( a 0 a 1 ⋯ a k ) p m = ( b 0 b 1 ⋯ b k ) p ( n m ) ≡ Π i = 0 k ( a i b i ) ( m o d p ) ( n m ) = ( n m o d p m m o d p ) × ( ⌊ n p ⌋ ⌊ m p ⌋ ) m o d p n = (a_0a_1\cdots a_k)_p\\m = (b_0b_1\cdots b_k)_p\\\tbinom{n}{m} \equiv \Pi_{i = 0}^{k} \tbinom{a_i}{b_i} \pmod p\\\tbinom{n}{m} = \tbinom{n \bmod p}{m \bmod p} \times \tbinom{\lfloor\frac{n}{p}\rfloor}{\lfloor\frac{m}{p}\rfloor} \bmod p n=(a0a1⋯ak)pm=(b0b1⋯bk)p(mn)≡Πi=0k(biai)(modp)(mn)=(mmodpnmodp)×(⌊pm⌋⌊pn⌋)modp
证明略。代码如下:
int calc (int n,int m)
{
if (n < m) return 0;
return 1ll * fac[n] * inv(fac[m]) % MOD * inc (fac[n - m]) % MOD;
}
int lucas (int m,int m)
{
if (!m) return 1;
return 1ll * lucas (n / MOD,m / MOD) * clac (n % MOD,m % MOD) % MOD;
}
8408

被折叠的 条评论
为什么被折叠?



