hdu 多校容斥
从0-(n-1)选m个数和为k的方案数
设f[i]为有i个位置大于n的方案
f[0]=all-(f[1]∪f[2]∪f[3]。。)
=all-f[1]-f[2]..+(f[1]∩f[2])。。。
奇减偶加
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; typedef long long ll; const ll mod=998244353; const ll maxn=1e6+5; ll A[5*maxn],FA[5*maxn]; ll qpow(ll a,ll b) { ll ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } void init() { ll i; A[0]=1; FA[0]=1; for(i=1; i<=3*maxn; i++) A[i]=A[i-1]*i%mod; FA[2*maxn]=qpow(A[2*maxn],mod-2); for(i=2*maxn;i>1;i--) FA[i-1]=FA[i]*i%mod; } ll cp(ll n,ll m) { if(m>n) return 0; return A[n]*FA[n-m]%mod*FA[m]%mod; } int main() { ll i,j,k,n,m,t; ll num,sum,ans,p; init(); scanf("%I64d",&t); while(t--) { scanf("%I64d%I64d%I64d",&n,&m,&k); ans=cp(k+m-1,m-1); for(i=1;i<=(k/n);i++) { if(i&1) ans-=(cp(m,i)*cp(k-i*n+m-1,m-1)%mod); else ans+=(cp(m,i)*cp(k-i*n+m-1,m-1)%mod); ans=(ans+mod)%mod; } ans=ans%mod+mod; printf("%I64d\n",ans%mod); } return 0; }