卡特兰数

Posted wzc521

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了卡特兰数相关的知识,希望对你有一定的参考价值。

卡特兰数又称卡塔兰数(Catalan Number),是组合数学中一个经常出现在各种计数问题中的数列。


公式

  1.递归公式1:

    $f(n)=\sum \limits_i=0^n-1f(i)\times f(n-i-1)$

  2.递归公式2:

    $f(n)=\fracf(n-1)\times (4\times n-2)n+1$

  3.组合公式1:

    $f(n)=\fracC_2n^nn+1$

  4.组合公式2:

    $f(n)=C_2n^n-C_2n^n-1$


代码实现

  1.$n \leqslant 35$

  大了会爆long long

void Catalan()

	long long cat[36];
	cat[0]=cat[1]=1;
	for(int i=2;i<36;i++)
	
		cat[i]=0;
		for(int j=0;j<i;j++)
			cat[i]=cat[i]+cat[j]*cat[i-j-1];
	

  2.$n>35$求$cat(n)\mod p$,借助$Lucas$定理

  $Lucas$定理$\downarrow$

long long fac[N];
long long qpow(long long x,long long y,long long p)

	long long res=1;
	while(y)
	
		if(y%2)res=(res*x)%p;
		y>>=1;
		x=(x*x)%p;
	
	return res;

long long get_C(long long x,long long y,long long p)

	if(x<y)return 0;
	return fac[x]%p*qpow(fac[x-y]*fac[y]%p,p-2,p)%p;

long long lucas(long long x,long long y,long long p)

	if(!y)return 1;
	return (get_C(x%p,y%p,p)*lucas(x/p,y/p,p))%p;

  3.利用高精计算卡特兰大数

#include<bits/stdc++.h>
using namespace std;
int n,m;
long long a[100000],c[100000];
int mu[5001];
void mul(int p)

	int x=0,j;
	for(j=1;j<=a[0];j++)
	
		a[j]=a[j]*p+x;
		x=a[j]/10;
		a[j]%=10;
	
	a[j]=x;
	while(a[j]>9)
	
		a[j+1]=a[j]/10;
		a[j]%=10;
		j++;
	
	while(a[j]==0&&j>1)j--;
	a[0]=j;

void chu(int b)
        
    int x=0,s=0,t=0;
    memset(c,0,sizeof(c));
    for(int i=1;i<=a[0];i++)
    
        x=x*10+a[i];
        if(x/b!=0)s++;
        if(s==0)continue;
        c[++t]=x/b;
        x%=b;
    
    for(int i=1;i<=t;i++)
    	a[i]=c[i];
    a[0]=t;
     
int main()
	
	a[0]=a[1]=1;
	scanf("%d",&n);
	for(int i=n+2;i<=2*n;i++)mul(i);
	reverse(a+1,a+a[0]+1);
	for(int i=2;i<=n;i++)chu(i);
	for(int i=1;i<=a[0];i++)printf("%d",a[i]);


做题经验

  看见样例输入3,样例输出5,先想卡特兰数。

以上是关于卡特兰数的主要内容,如果未能解决你的问题,请参考以下文章

谁有卡特兰数的证明过程?

卡特兰数总结

卡特兰数

Catalan number (卡特兰数)

卡特兰数知识点

卡特兰数模板