牛客网 牛客小白月赛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 }