算法专题
加法原理
若完成一件事的方法有 n n n类,其中第 i i i类方法包括 a i a_i ai种不同的方法,且这些方法互不重合,则完成这件事情共有 ∑ a i \sum a_i ∑ai种方法。
乘法原理
若完成一件事需要 n n n个步骤,其中第 i i i个步骤有 a i a_i ai种不同方法,且这些步骤互不干扰,则完成这件事共有 ∏ a i \prod a_i ∏ai种方法
排列
定义
从
n
n
n个不同元素中选出
m
m
m个排成一列,问产生的排列数量
P
n
m
=
n
!
(
n
−
m
)
!
=
∏
i
=
0
m
−
1
(
n
−
i
)
P_{n}^{m}=\frac{n!}{(n-m)!}=\prod_{i=0}^{m-1}(n-i)
Pnm=(n−m)!n!=i=0∏m−1(n−i)
组合
定义
从
n
n
n个不同元素中选择
m
m
m个,不考虑次序,问方案数
C
n
m
=
n
!
m
!
(
n
−
m
)
!
=
P
n
m
m
!
C_{n}^{m}=\frac{n!}{m!(n-m)!}=\frac{P_{n}^{m}}{m!}
Cnm=m!(n−m)!n!=m!Pnm
性质
- C n m = C n n − m C_{n}^{m}=C_{n}^{n-m} Cnm=Cnn−m
- C n m = C n − 1 m − 1 + C n − 1 m C_{n}^{m}=C_{n-1}^{m-1}+C_{n-1}^{m} Cnm=Cn−1m−1+Cn−1m
- ( ∑ i = 0 n C n i ) = 2 n (\sum_{i=0}^{n}C_{n}^{i})=2^n (i=0∑nCni)=2n
POJ 1942 Paths on a grid
题目
给定一个 n ∗ m n*m n∗m的格子,问从左上角向上或向右走到右上角的方案数
分析
那么可以这样想,也就是题目求在 n + m n+m n+m个方向中选出 n n n个向右的方案数,那也就是 C n + m n C_{n+m}^{n} Cn+mn,然而这道题虽然好像数据很大,实际上数据非常弱,嗯,代码我就不贴了
二项式定理
定义
( a + b ) n = ∑ i = 0 n C n i a i b n − i (a+b)^n=\sum_{i=0}^nC_{n}^{i}a^ib^{n-i} (a+b)n=i=0∑nCniaibn−i
计算系数
题目大意
给定一个多项式 ( a x + b y ) k (ax+by)^k (ax+by)k,问多项式展开后 x n y m x^ny^m xnym的系数
分析
根据二项式定理,
(
a
x
+
b
y
)
k
=
∑
i
=
0
k
C
k
i
(
a
x
)
i
(
b
y
)
n
−
i
(ax+by)^k=\sum_{i=0}{k}C_{k}^{i}(ax)^i(by)^{n-i}
(ax+by)k=i=0∑kCki(ax)i(by)n−i
所以
x
n
y
m
x^ny^m
xnym的系数是
C
k
n
a
n
b
m
C_{k}^{n}a^nb^m
Cknanbm
卡特兰数
定义
给定 n n n个0和 n n n个1,它们按照某种顺序排成长度为 2 n 2n 2n的序列,满足任意前缀中0的个数不少于1的个数的序列数量是 C 2 n n n + 1 \frac{C_{2n}^{n}}{n+1} n+1C2nn
多重集的排列数
定义
设
S
=
{
n
1
∗
a
1
,
n
2
∗
a
2
,
…
,
n
k
∗
a
k
}
,
n
=
n
1
+
n
2
+
⋯
+
n
k
S=\{n_1*a_1,n_2*a_2,\dots,n_k*a_k\},n=n_1+n_2+\dots+n_k
S={n1∗a1,n2∗a2,…,nk∗ak},n=n1+n2+⋯+nk
那么
S
S
S的全排列数为
n
!
n
1
!
n
2
!
…
n
k
!
\frac{n!}{n_1!n_2!\dots n_k!}
n1!n2!…nk!n!
洛谷 4778 Counting Swaps
题目
把一个 1 ∼ n 1\sim n 1∼n的排列每次可以选择两个数交换,若变成 1 , 2 , … , n 1,2,\dots,n 1,2,…,n最少需要 m m m次变换,问有多少种方法可以只需 m m m次变换就能变成单调递增的排列
分析
首先把一个长度为
n
n
n的环变成自环最少需要
n
−
1
n-1
n−1次变换,设
f
[
n
]
f[n]
f[n]表示用最少步数把一个长度为
n
n
n的环变成自环的操作数,通过打表或OEIS可以知道
f
[
n
]
=
n
n
−
2
f[n]=n^{n-2}
f[n]=nn−2,接着这个排列会被分成若干个环,显然
n
−
1
n-1
n−1种变换是可以对调的,所以也就化为多重集的排列数,答案就是
(
n
−
k
)
!
∏
i
=
1
k
(
p
i
−
1
)
!
∏
i
=
1
k
p
i
p
i
−
2
\frac{(n-k)!}{\prod_{i=1}^k(p_i-1)!}\prod_{i=1}^{k}p_i^{p_i-2}
∏i=1k(pi−1)!(n−k)!i=1∏kpipi−2
多重集的组合数
定义1 ( r ≤ n i ) (r\leq n_i) (r≤ni)
设 S = { n 1 ∗ a 1 , n 2 ∗ a 2 , … , n k ∗ a k } S=\{n_1*a_1,n_2*a_2,\dots,n_k*a_k\} S={n1∗a1,n2∗a2,…,nk∗ak},挑出 r r r个元素组成无序的集合的方案为 C k + r − 1 k − 1 C_{k+r-1}^{k-1} Ck+r−1k−1
定义2 ( r ≤ n ) (r\leq n) (r≤n)
= C k + r − 1 k − 1 − ∑ i = 1 k C k + r − n i − 2 k − 1 + ∑ 1 ≤ i < j ≤ k C k + r − n i − n j − 3 k − 1 − ⋯ + ( − 1 ) k C k + r − ∑ i = 1 k n i − ( k + 1 ) k − 1 =C_{k+r-1}^{k-1}-\sum_{i=1}^{k}C_{k+r-n_i-2}^{k-1}+\sum_{1\leq i<j\leq k}C_{k+r-n_i-n_j-3}^{k-1}-\dots +(-1)^kC_{k+r-\sum_{i=1}^{k}n_i-(k+1)}^{k-1} =Ck+r−1k−1−i=1∑kCk+r−ni−2k−1+1≤i<j≤k∑Ck+r−ni−nj−3k−1−⋯+(−1)kCk+r−∑i=1kni−(k+1)k−1
CF451E Devu and Flowers
题目
Devu有 n n n个盒子,第 i i i个盒子中有 a i a_i ai枝相同的花,不同盒子的花不相同,现在选出 m m m朵,问共有多少种方案。若两束花每种颜色的花数量都相同,即为同一方案
分析
显然可知,这道题求的是多重集的组合数,但怎么实现呢,可以用一个二进制表示选择的盒子,那这样就可以实现容斥了,接着由于 m m m很大, n n n很小,可以用之前的方法 O ( n ) O(n) O(n)解决,那总时间复杂度就是 O ( 2 n n ) O(2^nn) O(2nn)
Lucas定理
定义
若
p
p
p是质数,则对于任意整数
1
≤
m
≤
n
1\leq m\leq n
1≤m≤n,有:
C
n
m
≡
C
n
 
m
o
d
 
p
m
 
m
o
d
 
p
∗
C
n
/
p
m
/
p
(
 
m
o
d
 
p
)
C_{n}^{m}\equiv C_{n\bmod p}^{m\bmod p}*C_{n/p}^{m/p}(\bmod p)
Cnm≡Cnmodpmmodp∗Cn/pm/p(modp)
HDU 3037 Saving Beans
题目
有 n n n个不同的盒子,在每个盒子中放一些球,也可不放,使得总球数小于等于 m m m,求方案数 (   m o d   p ) (\bmod p) (modp)( 1 ≤ n , m ≤ 1 0 9 , 1 < p < 1 0 5 1\leq n,m\leq 10^9,1<p<10^5 1≤n,m≤109,1<p<105)
分析
这道题等价于有 n + 1 n+1 n+1个不同的盒子,在每个盒子中放一些球,也可不放,使得总球数等于 m m m,那么可以用隔板法得到答案就是 C n + m m C_{n+m}^{m} Cn+mm,也就是加强版的P3807 【模板】卢卡斯定理,然后尝试用逆元,但是在这里TLE了,然后用费马小定理AC???,在洛谷还快了20ms,还是我太菜了
HDU 5226 Tom and matrix
题目
求 ∑ i = x 1 x 2 ∑ j = y 1 y 2 C i j \sum_{i=x1}^{x2}\sum_{j=y1}^{y2}C_{i}^{j} i=x1∑x2j=y1∑y2Cij
分析
原式=
∑
j
=
y
1
+
1
y
2
+
1
C
x
2
+
1
j
−
C
x
1
j
\sum_{j=y1+1}^{y2+1}C_{x2+1}^{j}-C_{x1}^{j}
j=y1+1∑y2+1Cx2+1j−Cx1j
但是
2
≤
p
<
1
0
9
2\leq p<10^9
2≤p<109
所以要用到
l
u
c
a
s
lucas
lucas,而且预处理阶乘和逆元保持在
1
0
5
10^5
105的范围内
洛谷 2480 古代猪文
题目
求 G ∑ d ∣ n C n d   m o d   9999911659 G^{\sum_{d|n}C_{n}^{d}} \bmod 9999911659 G∑d∣nCndmod9999911659
分析
首先特判
G
=
9999911659
G=9999911659
G=9999911659的情况,关键是求
∑
d
∣
n
C
n
d
\sum_{d|n}C_{n}^{d}
∑d∣nCnd,然后根据欧拉定理的推论得到
G
∑
d
∣
n
C
n
d
≡
G
∑
d
∣
n
C
n
d
 
m
o
d
 
9999911658
(
 
m
o
d
 
9999911658
)
G^{\sum_{d|n}C_{n}^{d}}\equiv G^{\sum_{d|n}C_{n}^{d} \bmod 9999911658} (\bmod 9999911658)
G∑d∣nCnd≡G∑d∣nCndmod9999911658(mod9999911658)
所以关键就是求
∑
d
∣
n
C
n
d
m
o
d
  
999911658
\sum_{d|n}C_{n}^{d}\mod 999911658
∑d∣nCndmod999911658
可以发现
999911658
=
2
×
3
×
4679
×
35617
999911658=2\times 3\times 4679\times 35617
999911658=2×3×4679×35617,那么我们把
∑
d
∣
n
C
n
d
\sum_{d|n}C_{n}^d
∑d∣nCnd分成四个质数去求答案,用lucas定理,然后再用CRT求出线性同余方程组的最小非负整数解,嗯,就是这个样子
后续
完结,撒花