Catalan 卡特兰数
定义
- 给定 n 个 0 和 n 个 ** 1**,它们将按照某种顺序排成长度为 **2n ** 的序列,求它们能排列成的所有序列中,能够满足任意前缀序列中 0 的个数都不少于 **1 ** 的个数的序列有多少个。
计算
C a t n = C 2 n n 2 Cat_n = \frac{C_{2n}^n}{2} Catn=2C2nn
证明
- 运用数形结合思想,将问题进行转化:
推论
- 求n个左括号与右括号组成的合法括号序列个数为:
C a t n Cat_n Catn - [1,n]经过一个stack,得到的合法出栈序列数:
C a t n Cat_n Catn - n个节点构成的不同二叉树个数:
C a t n Cat_n Catn
代码
int quickmi(int a,int k,int p)
{
int res = 1;
while(k){
if(k&1){
res = (long long)res * a % p;
}
a = (long long)a * a;
k >>= 1;
}
return res;
}
int catalan(int n,int mod)
{
int a = n * 2, b = n;
int res = 1;
for (int i = a; i > a - b; i--)
res = (long long)res * i % mod;
for (int i = 1; i <= b; i++)
res = (long long)res * quickmi(i, mod - 2, mod) % mod;
res = (long long)res * quickmi(n + 1, mod - 2, mod) % mod;
}