牛客网 Wannafly挑战赛11 B.白兔的式子-组合数阶乘逆元快速幂
链接:https://www.nowcoder.com/acm/contest/73/B
来源:牛客网
B.白兔的式子
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
已知f[1][1]=1,f[i][j]=a*f[i-1][j]+b*f[i-1][j-1](i>=2,1<=j<=i)。
对于其他情况f[i][j]=0
有T组询问,每次给出a,b,n,m,求f[n][m] mod (998244353)
输入描述:
第一行为一个整数T,表示询问个数。
接下来一共T行,每行四个整数a,b,n,m。
输出描述:
一共T行,每行一个整数,表示f[n][m] mod (998244353)
示例1
输入
2 2 3 3 3 3 1 4 1
输出
9 27
备注:
T<=100000
1<=m<=n<=100000
0<=a,b<=109
这个题打个表能发现和杨辉三角有关系,小小了解一下
这个题就是所求位置对应的杨辉三角的系数,然后乘a的幂和b的幂。
因为数很大,不能直接用杨辉三角写,因为杨辉三角的系数也是组合数的阶乘相除,就要用到逆元。
求出来系数之后再用快速幂算一下a的幂和b的幂,就可以了。
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 typedef long long ll; 8 const int maxn=1e5+10; 9 const int mod=998244353; 10 ll f[maxn]; 11 ll t,a,b,n,m; 12 void ff() 13 { 14 f[0]=1; 15 for(int i=1;i<=100005;i++) 16 f[i]=(i*f[i-1])%mod; 17 } 18 ll poww(ll n,ll m)//快速幂 19 { 20 ll ans = 1; 21 while(m > 0) 22 { 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 { 31 ll ans=f[n]; 32 ans=(ans*poww(f[m],mod-2))%mod; 33 ans=(ans*poww(f[n-m],mod-2))%mod; 34 return ans; 35 } 36 int main(){ 37 ff(); 38 int t; 39 int a,b,n,m; 40 cin>>t; 41 while(t--){ 42 cin>>a>>b>>n>>m; 43 ll xishu=cc(n-1,m-1); 44 ll xa=poww(a,n-m); 45 ll xb=poww(b,m-1); 46 ll ans=((xishu*xa)%mod*xb)%mod; 47 cout<<ans<<endl; 48 } 49 }