【数学】组合数学
组合数
定义
\(\large\binom{n}{m} = \frac{n!}{m!\times(n-m)!}\)
性质
-
\(\large\binom{n}{m} = \binom{n-1}{m}+\binom{n-1}{m-1}\)
-
\(\large\sum\limits_{i = 0}^{n}\binom{n}{i} = 2^n\)
-
\(\large\sum\limits_{i = 0}^{n}(-1)^i\binom{n}{i} = \left[n = 0\right]\)
-
\(\large\sum\limits_{i = 0}^{m}\binom{n}{i}\binom{m}{m-i} = \binom{m+n}{m}\) \(\large(if\ n == m)\sum\limits_{i = 0}^{n}\binom{n}{i}^2 = \binom{2n}{n}\)
-
\(\sum\limits_{i = 0}^{n}i^2\)
-
\(\large\sum\limits_{i = 0}^{n}\binom{i}{k} = \binom{n+1}{k+1}\)
-
\(\large\sum\limits_{i = 0}^{n}\binom{n-i}{i} = F_{n+1}\)
康托展开
#include <stdio.h>
#include <string.h>
#include <math.h>
const int z = 65536;
struct BIT {
int tree[z];
int maxn;
#define lowbit(x) (x&(-x))
int query(int pos) {
int res = 0;
for(pos;pos > 0;pos -= lowbit(pos))
res += tree[pos];
return res;
}
int query(int l,int r) {
return query(r)-query(l-1);
}
void modify(int pos,int val) {
for(pos;pos <= maxn;pos += lowbit(pos))
tree[pos] += val;
}
#undef lowbit
void init(int size) {
memset(tree,0,(maxn+1)*sizeof(int));
maxn = size;
}
} bit;
int fact[z], tot;
int getfact(int x) {
if(!fact[x]) {
for(tot++;tot <= x;++tot)
fact[tot] = fact[tot-1]*tot;
}
return fact[x];
}
int n;
int rank;
void Cantor() {
scanf("%d",&n);
rank = 0;
fact[0] = fact[1] = 1;
tot = 1;
bit.init(n);
for(int i = 1, tmp;i <= n;++i) {
scanf("%d",&tmp);
int k = tmp-bit.query(tmp)-1;
bit.modify(tmp,k);
printf(" > %d\n",k);
rank += k*getfact(n-i);
}
rank++;
printf("%d",rank);
}
void reCantor() {
scanf("%d %d",&n,&rank);
rank--;
fact[0] = fact[1] = 1;
tot = 1;
bit.init(n);
for(int i = n, tmp;i >= 1;--i) {
tmp = (int)floor(1.0*rank/getfact(i-1));
int k = tmp+1;
while(bit.query(k) >= k-tmp) k++;
bit.modify(k,1);
printf("%d ",k);
rank -= tmp*getfact(i-1);
}
}
signed main() {
//to do;
}
明安图-卡特兰数
1.\(\large \operatorname{Cat}_n = \sum\limits_{i=0}^{n}(\operatorname{Cat}_i\times\operatorname{Cat}_{n-i})\)
2.\(\large(n-3)\operatorname{Cat}_n=\frac{n}{2}\times\sum\limits_{i=3}^{n-1}(\operatorname{Cat}_i\times\operatorname{Cat}_{n+2-i})\)
3.\(\large\operatorname{Cat}_n=\operatorname{Cat}_{n-1}\times\frac{4\cdot n-2}{n+1}\)
4.\(\large\operatorname{Cat}_n=\frac{\binom{2\cdot n}{n}}{n+1}\)
5.\(\large\operatorname{Cat}_n=\binom{2\cdot n}{n}-\binom{2\cdot n}{n-1}\)
ull C(ull u,ull d,ull p) {
return fact[u]*inv[d]%p*inv[u-d]%p;
}
ull Cat(ull a,ull p) {
return C(a<<1,a,p)-C(n<<1,n-1);
}
错排
错排
我们定义\(\operatorname{cross}_i\)为对于一个给定排列\(\{P_i\}\),保证\(\forall i,P_i \not = S_i\)的排列\(S_i\)的个数。
则有
以及
顺便
扩展
定义\(\operatorname{exc}_{n,k}\)为正常错排过程中有\(k\)个元素没有限制所产生的排列数。
如:
P : 1 2 3
S : 2 3 4
\(S\)中\(4\)无限制,可以放在任意位置。
则有:
边界是:
分拆数
分拆与分拆数
分拆:将自然数 \(n\) 写成递降正整数和的表示。
分拆数: \(p_n\) ,即自然数 \(n\) 的拆分方法数。
k 部分拆数
\(k\) 部分拆数:将 \(n\) 分成恰有 \(k\) 个部分的分拆,称为 \(k\) 部分拆数,记作 \(p_{n,k}\) 。
显然 \(p_{n,k}\) 为 \(k\) 元一次方程:
的解数(之所以有 \(n-k\) 是为了保证每一部分大于零)。
如果此方程有 \(l\) 个部分非零,则有新方程:
解数为 \(p_{n-k,l}\) 。
因此:
而
所以有:
Ferrers 图
Ferrers 图
:将分拆的每个部分用点组成的行表示,每行点的个数为这个部分的大小。
如分拆 \(12 = 5+4+2+1\) 的 Ferrers 图
为:
⬤ | ⬤ | ⬤ | ⬤ | ⬤ |
---|---|---|---|---|
⬤ | ⬤ | ⬤ | ⬤ | |
⬤ | ⬤ | |||
⬤ |
共轭 : 将一个 Ferrers 图
沿着对角线翻转,得到的新 Ferrers 图
称为原图的 共轭;新分拆称为原分拆的共轭。
如分拆 \(12 = 5+4+2+1\) 的共轭为: \(12 = 4+3+2+2+1\) 。其 Ferrers 图
的共轭为:
⬤ | ⬤ | ⬤ | ⬤ |
---|---|---|---|
⬤ | ⬤ | ⬤ | |
⬤ | ⬤ | ||
⬤ | ⬤ | ||
⬤ |
最大 k 分拆数
最大 \(k\) 分拆数:自然数 \(n\) 的最大部分为 \(k\) 的分拆个数。
根据共轭, \(n\) 最大 \(k\) 分拆数 \(=\) \(k\) 部分拆数。
互异分拆数
互异分拆数:\(pd_n\) ,自然数 \(n\) 的各部分互不相同的分拆方法数。
互异 \(k\) 部分拆数: \(pd_{n,k}\) ,自然数 \(n\) 的分成 \(k\) 部分的互异分拆方法数。
方法类似上面。