牛客网 牛客小白月赛1 I.あなたの蛙が帰っています-卡特兰数,组合数阶乘逆元快速幂

 

I.あなたの蛙が帰っています
 
 
 
这个题有点意思,是卡特兰数,自行百度就可以。卡特兰数用处很多,买票问题,出栈问题,括号配对等。传送门:很厉害
这个题就是出栈问题,问你出栈的方式有多少种。因为第一个不能最先输出来,随便写写就好了。
找出来公式就是C(2n,n)-C(2n,n-1)。对于这个题来说就是(C(2n,n)-C(2n,n-1)) - (C(2m,m)-C(2m,m-1))。
组合数就用到阶乘了(想一下平时手算的步骤),阶乘逆元快速幂,哗哗哗乱写就可以了。
 
代码:
 1 //I-卡特兰数-组合数学-阶乘逆元快速幂
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<cstdlib>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<vector>
10 using namespace std;
11 typedef long long ll;
12 const int maxn=2*1e5+10;
13 const int mod=998244353;
14 ll f[maxn];
15 void ff(){
16     f[0]=1;
17     for(int i=1;i<maxn;i++)
18         f[i]=(i*f[i-1])%mod;
19 }
20 ll poww(ll n,ll m){   //快速幂
21     ll ans=1;
22     while(m){
23         if(m&1)ans=(ans*n)%mod;
24         m=m>>1;
25         n=(n*n)%mod;
26     }
27     return ans;
28 }
29 ll cc(ll n,ll m){      //组合数
30     ll ans=f[n];
31     ans=(ans*poww(f[m],mod-2))%mod;
32     ans=(ans*poww(f[n-m],mod-2))%mod;
33     return ans;
34 }
35 int main(){
36     int t,n,m,h=0;
37     ff();
38     cin>>t;
39     while(t--){
40         cin>>n;
41         m=n-1;
42         ll ans=(cc(2*n,n)-cc(2*n,n-1)-cc(2*m,m)+cc(2*m,m-1)+2*mod)%mod;
43         cout<<"Case #"<<++h<<": "<<ans<<endl;
44     }
45 }

 

 

 

 

posted @ 2018-03-18 22:31  ZERO-  阅读(322)  评论(0编辑  收藏  举报