版权声明:本文为博主原创文章,转载请附上原博客链接。 https://blog.csdn.net/Dale_zero/article/details/82121132
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6397
结论1:m个大于等于0的数字组成k有C(m+k-1,m-1)种方案
当有x人的取值>=n时,原式x1+x2+..xm=k,将每个大于n的数减n,就变成了x1+x2+...+xn=k-x*n,就可以用结论1求解了。
容斥求解奇数就取减号,偶数取加号。
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define mod 998244353
#define For(i,m,n) for(int i=m;i<=n;i++)
#define Dor(i,m,n) for(int i=m;i>=n;i--)
#define LL long long
#define lan(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=200010;
LL mx;
LL fac[maxn], inv[maxn];
int powi(LL a,LL b)
{
int c = 1;
for (; b; b >>= 1, a = 1ll * a * a % mod)
if (b & 1) c = 1ll * c * a % mod;
return c;
}
LL C(LL a, LL b)///a>b
{
if(a==b) return 1;
else if(a<b) return 0;
return 1ll * fac[a] * inv[b] % mod * inv[a - b] % mod;
}
///初始化
void init()
{
mx = maxn-1;///开的数组大小
fac[0] = 1; for (int i = 1; i <= mx; ++ i) fac[i] = 1ll * fac[i - 1] * i % mod;
inv[mx] = powi(fac[mx], mod - 2); for (int i = mx - 1; ~i; -- i) inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
}
int main()
{
int t;
scanf("%d",&t);
init();
while(t--)
{
LL n,m,k;
scanf("%lld%lld%lld",&n,&m,&k);
LL ans=C(m+k-1,m-1);
for(int i=1;n*i<=k;i++)
{
if(i&1)
ans=(ans+mod-(C(m+k-1-i*n,m-1)*C(m,i))%mod)%mod;
else
ans=(ans+(C(m+k-1-i*n,m-1)*C(m,i)))%mod;
}
printf("%lld\n",ans);
}
return 0;
}