Wannafly 挑战赛11 B白兔的式子

题链接:点击打开链接

题目描述

已知 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进行取余

解题思路: 我们先求一些简单的位置上的值,然后很容易发现是杨辉三角的关系。


Wannafly 挑战赛11 B白兔的式子_第1张图片


然后就是总结公式: F[N][M]=Cn-1 M-1 a^(n-m)b^m-1;

打表求阶乘,逆元求解排列组合C 快速幂求公式后两项

(GET 逆元)

#include
#include
#include
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;
}

 
 

你可能感兴趣的:(Wannafly,逆元)