题链接:点击打开链接
题目描述
已知
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,n,m 然后让你根据题目给的式子计算出相应的值,对998244353进行取余
解题思路: 我们先求一些简单的位置上的值,然后很容易发现是杨辉三角的关系。
然后就是总结公式: F[N][M]=Cn-1 M-1 a^(n-m)b^m-1;
打表求阶乘,逆元求解排列组合C 快速幂求公式后两项
(GET 逆元)
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
const int mo=998244353;
long long a,b,n,m;
long long num[maxn];
int t;
long long get(long long a,long long num){
long long as=1;
while(num){
if(num&1){
as*=a;
as%=mo;
}
a*=a;
a%=mo;
num/=2;
}
return as;
}
//ax = 1(mod n)
void ex_gcd(long long a,long long b,long long &x,long long &y){
if(!b){x=1;y=0;return;}
ex_gcd(b,a%b,y,x);
y-=a/b*x;
}
long long mod_rev(long long a,long long n) {
long long x,y;
ex_gcd(a,n,x,y);
return (x+n)%n;
}
int main(){
int i,j;
num[0]=1;
num[1]=1;
for(i=2;i<=100000;i++){
num[i]=num[i-1]*i;
num[i]%=mo;
}
scanf("%d",&t);
while(t--){
scanf("%lld%lld%lld%lld",&a,&b,&n,&m);
long long ans1=get(a,n-m);
long long ans2=get(b,m-1);
n--;m--;
long long k1=mod_rev(num[m],mo);
long long k2=mod_rev(num[n-m],mo);
long long ans=num[n];
ans*=k1;ans%=mo;
ans*=k2;ans%=mo;
ans*=ans2;ans%=mo;
ans*=ans1;ans%=mo;
printf("%lld\n",ans);
}
return 0;
}