题(liu_runda的神题)(卡特兰数,组合数)

Posted wwb123

tags:

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

考场的SB经验不再分享

case 0:

一道组合计数的水题,具体不再讲可以看以前的相似题

case 1:

很明显的卡特兰计数,我们把长度为n的序列看成01串

由此可知我们需要满足从1——n中前缀1的数量不少于前缀0的数量

case 2:

满足可以在坐标轴上移动

设f[i]表示第i步回到原点,我们枚举第j步第一次回到起点

那么f[i]数组里就不会出现重复,这样可以保证正确性

同时要再次用到卡特兰数:

   我们发现定义的特殊j是第一次回到起点,但cal中可以多次回到起点

但我们可以发现只要我们满足在1-j-1满足前缀和>=1即可,这样我们可以

发现现在序列一部分确定设正方向为1

    1 1 .........0 0

这样中间部分就又是一个cal,这样我们直接乘cal(j/2-1)即可

(注意可能j是四个方向,于是乘4)

case 3:

同时在两轴及第一象限

直接用组合数,乘两个方向的cal即可

 

技术图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<stack>
 8 #include<map>
 9 #include<queue>
10 #define ps push_back
11 #define MAXN 1000001
12 #define ll long long
13 using namespace std;
14 ll n;
15 const ll mod=1000000007;
16 ll jie[MAXN],ni[MAXN],ni_c[MAXN];
17 ll C(ll x,ll y)
18 
19     if(y>x)return 0;
20     return jie[x]*ni_c[y]%mod*ni_c[x-y]%mod;
21 
22 ll cal(ll x)
23 
24      return C(x*2,x)*ni[x+1]%mod;
25 
26 ll f[MAXN];
27 int main()
28 
29       ll orz;
30       scanf("%lld%lld",&n,&orz);
31       jie[0]=1;jie[1]=1;
32       ni[0]=1;ni[1]=1;
33       ni_c[0]=1;ni_c[1]=1;
34       for(ll i=2;i<=2*n+10;++i)
35       
36          jie[i]=(jie[i-1]*i)%mod;
37          ni[i]=((mod-mod/i)*ni[mod%i])%mod;
38          ni_c[i]=(ni_c[i-1]*ni[i])%mod;
39       
40       ll ans=0;
41       if(orz==0)
42       
43           for(ll i=0;i<=n;i+=2)
44           
45                ans=(ans+C(n,i)*C(i,i/2)%mod*C(n-i,(n-i)/2))%mod;
46           
47           printf("%lld\n",ans%mod);
48       
49       else if(orz==1)
50       
51           if(n%2==1)
52                printf("0\n");
53           else
54                printf("%lld\n",(C(n,n/2)%mod*ni[n/2+1]%mod+mod)%mod);
55       
56       else if(orz==3)
57       
58           for(ll i=0;i<=n;i+=2)
59           
60                ll th=C(n,i);
61                if((n-i)%2==1)continue;
62                ans=(ans+th*cal(i/2)%mod*cal((n-i)/2))%mod;
63                
64           printf("%lld\n",ans);
65       
66       else if(orz==2)
67       
68            f[0]=1;
69            for(ll i=2;i<=n;i+=2)
70            
71                for(ll j=0;j<=i;j+=2)
72                
73                     f[i]=(f[i]+4*f[i-j]*cal(j/2-1))%mod;
74                
75            
76            printf("%lld\n",f[n]);
77       
78 
View Code

 

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

数论基础题 费马引理+卡特兰数+Lucas定理+同余方程+扩欧

BZOJ 3907网格 组合数学

卡特兰数相关

卡特兰数(Catalan Number) 算法数论 组合~

组合数学卡特兰数 / 大施罗德数 相关

组合数学卡特兰数 / 大施罗德数 相关