题意:给T组数,n,m,k从0~n-1中选m个数之和为k个方法数对998244353取模输出
题解:
- 对于x1+x2+x3+....+xm=k(xi>=0)有C(k+m-1,m-1)个解
- a是不能被质数p整除的正整数 a^(p-1)≡1(modp) --> a^(p-2)=1/a(modp) 则a^p-2为a的逆元
对于x1,x2,x3,....xm,若符合条件 xi<n--->xi'=xi
不符合条件 xi>n---->xi'=xi-n
则x1+x2+.....+xm=k-c*n在有c个不符合情况的条件下有C(k-c*n+m-1,m-1)个解
容斥原理枚举不符合条件的个数
容斥求和:C(n,0)-C(n,1)+C(n,2)-C(n,3)+C(n,4)-......+(-1)^m*C(n,m)
#include <stdio.h>
#include <iostream>
using namespace std;
const int MOD=998244353;
const int MAXN=202020;
int fac[MAXN],facinv[MAXN];
long long quickmul(int a,int b)
{
long long ret=1;
for(; b ; b >>=1 ,a =(long long) a * a % MOD)
if((b & 1))
ret=ret * a % MOD;
return ret;
}
long long C(int n,int m)
{
if(n<0||m<0||n<m)
return 0;
return (long long)fac[n]*facinv[m]%MOD*facinv[n-m]%MOD;
}
void init()
{
fac[0]=1;
for(int i=1;i<=MAXN;i++)
fac[i]=(long long)fac[i-1]*i%MOD;
facinv[MAXN]=quickmul(fac[MAXN],MOD-2);
for(int i=MAXN;i>0;i--)
facinv[i-1]=(long long)facinv[i]*(i)%MOD;
//1/(i-1)!=i/(i)!
}
void solve()
{
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
int ans=0;
for(int c=0;c*n<=k;c++)
{
if((c&1))
{
ans=(ans - C(m,c) * C(k - c*n + m-1, m-1) % MOD + MOD ) % MOD;
}else
{
ans=(ans + C(m,c) * C(k - c*n + m-1, m-1) % MOD ) % MOD;
}
}
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
init();
while(T--)
{
solve();
}
return 0;
}