组合数_卡特兰定理

Posted 一只特立独行的猫

tags:

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

当求前缀排列问题时,可以尝试将纯数学的逻辑转换为几何的逻辑。
例:
给定 n 个 0 和 n 个 1,它们将按照某种顺序排成长度为 2n 的序列,求它们能排列成的所有序列中,能够满足任意前缀序列中 0 的个数都不少于 1
的个数的序列有多少个。输出的答案对 109+7取模。
思路

将问题转换为从左下角走到右上角,0往右走,1往上走。就是总的路径数减去经过上红线的路径数。经过上红线的路径按上红线进行对称,一定能走到(n-1,n+1)
即计算 C 2 n n − C 2 n n − 1 C_{2n}^n-C_{2n}^{n-1} C2nnC2nn1的值
卡特兰定理:

C 2 n n − C 2 n n − 1 = ( 2 n ) ! n ! n ! − 2 n ! ( n − 1 ) ! ( n + 1 ) ! = 2 n ! n ! ( n + 1 ) ! = 1 n + 1 2 n ! n ! n ! = 1 n + 1 C 2 n n C_{2n}^n-C_{2n}^{n-1}= \\frac {(2n)!} {n!n!}-\\frac{2n!}{(n-1)!(n+1)!}=\\frac {2n!}{n!(n+1)!}=\\frac{1}{n+1} \\frac {2n!}{n!n!}=\\frac{1}{n+1}C_{2n}^{n} C2nnC2nn1=n!n!(2n)!(n1)!(n+1)!2n!=n!(n+1)!2n!=n+11n!n!2n!=n+11C2nn

接下来就是计算组合数的问题。

#include<iostream>

using namespace std;

typedef long long LL;
const LL mod = 1e9+7;

int n;

LL qmi(LL a,LL p,LL q){
	//快速幂求逆元
    LL res=1;
    while(p){
        if(p&1) res=res*a%q;
        a=a*a%q;
        p>>=1;
    }
    return res;
}

int main(){
    cin>>n;
    LL res=1;
    for(int i=2*n;i>n;i--) res=res*i%mod;
    for(int i=n;i>0;i--) res=res*qmi(i,mod-2,mod)%mod;
    res=res*qmi(n+1,mod-2,mod)%mod;
    cout<<res<<endl;
    return 0;
}

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

解题报告 (十六) 逆元

51Nod1120 机器人走方格 V3

任务表(知识总结)

卡特兰数(catalan)总结

CodeForces - 1204E Natasha, Sasha and the Prefix Sums (组合数学,卡特兰数扩展)

51nod 1120 机器人走方格 V3 卡特兰数 lucas定理