题意:
给定n, m, k;
本质上就是让你求下面这个不定方程的非负整数解的组数:
首先不考虑Xi的最大取值限制,用隔板法;由于Xi可以为0,处理的时候k要加上m,转化为Xi最低为1。
然后由于Xi限制了最大数量为n,答案等于上面的结果减去不合要求的数量。计算当有i个X值超过n时的解的个数时,先单独拿出i个n,结果转化为 (k=(k-n*i)时的满足要求的解的个数)*C(m,i)。
但是,k=(k-n*i)时的满足要求的解的个数 还是不可求。我们能求的是当k=(k-n*i)时,没有Xi<=n这个限制的解的个数。例如,当i=1时,如果直接没有限制的答案的基础上减去(C(m+k-n*1-1,m-1)*C(m,1)) ,则多减去了i=2时的情况,所以要加回去,以此类推,所以:
即可转化为金典的容斥模型。即:
→ 容斥原理
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=200010;
const int mod=998244353;
int T,n,m,k;
ll inv[M],fct[M];
ll Bpow(ll x,ll p){
ll res=1;
while(p){
if(p&1)res=res*x%mod;
p>>=1;x=x*x%mod;
}
return res;
}
void init(){
inv[0]=fct[0]=1;
for(int i=1;i<M;++i)fct[i]=fct[i-1]*i%mod;
inv[M-1]=Bpow(fct[M-1],mod-2);
for(int i=M-2;i>0;--i)inv[i]=inv[i+1]*(i+1)%mod;
}
ll C(int n,int m){
if(n<0||m<0||n<m)return 0;
if(m==0||n==m)return 1;
return fct[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(){
scanf("%d",&T);
init();
while(T--){
scanf("%d%d%d",&n,&m,&k);
ll now=0,f=1;
ll ans=0;
while(k>=now*n){
ans=(ans+mod+f*C(m,now)*C(k+m-1-now*n,m-1)%mod)%mod;
f*=-1;
now++;
}
printf("%lld\n",ans);
}
}