1. 程式人生 > >白兔的式子(費馬小定理+逆元)

白兔的式子(費馬小定理+逆元)

題目描述
已知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<=10^9
這裡寫圖片描述
我們利用費馬小定理來求C(n,m)。用快速冪來求後邊的兩項

#include<bits/stdc++.h>
using namespace std;
#define LL long long

const int N = 100000+11;
const int p = 998244353;

LL k[N];
void init(){
    k[0]=1;
    for(int i=1;i<=N;i++)
        (k[i]=k[i-1]*i)%=p;
}
LL qkm(LL a,LL b,LL c)  {
    LL s=1,base=a%c
; while(b){ if(b&1) s=s*base%c; base=base*base%c; b>>=1; } return s%c; } LL C(LL n,LL m,LL p){ return ( ( k[n]*qkm( ( k[n-m]*k[m]) %p , p-2 , p ) ) %p ); } int main(){ init(); int t;cin>>t; while(t--){ LL a,b,n,m;scanf("%lld
%lld%lld%lld"
,&a,&b,&n,&m); LL ans=1; ans=(ans*qkm(a,n-m,p))%p; ans=(ans*qkm(b,m-1,p))%p; ans=(ans*C(n-1,m-1,p))%p; printf("%lld\n",ans); } return 0; }