HDU6397
用小于n的m个数组成k,求方案数mod 998244353
如果没有n的限制,直接用隔板法求就可以
因为m个数中可以为0,所以不妨先都放上一个1,转化成不能为0的m个数来凑k+m,即C(k+m-1,m-1);
加了限制之后就用容斥原理去维护就好了
至少有i个不小于n的方案数为C(m,i)*C(k+m-1-i*n,m-1);
total-至少有一个不小于n+至少有2个不小于n的...
一定要小心阶乘的初始化啊,f[0]=1;
哭了
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #include<set> 8 #include<map> 9 #include<stack> 10 #include<cstring> 11 #define inf 2147483647 12 #define ls rt<<1 13 #define rs rt<<1|1 14 #define lson ls,nl,mid,l,r 15 #define rson rs,mid+1,nr,l,r 16 #define N 100010 17 #define mod 998244353 18 #define For(i,a,b) for(long long i=a;i<=b;i++) 19 #define p(a) putchar(a) 20 #define g() getchar() 21 22 using namespace std; 23 long long T; 24 long long n,m,k; 25 long long f[1000010],In[1000010],fin[1000010]; 26 long long ans; 27 void in(long long &x){ 28 long long y=1; 29 char c=g();x=0; 30 while(c<'0'||c>'9'){ 31 if(c=='-')y=-1; 32 c=g(); 33 } 34 while(c<='9'&&c>='0'){ 35 x=(x<<1)+(x<<3)+c-'0';c=g(); 36 } 37 x*=y; 38 } 39 void o(long long x){ 40 if(x<0){ 41 p('-'); 42 x=-x; 43 } 44 if(x>9)o(x/10); 45 p(x%10+'0'); 46 } 47 48 void pre(){ 49 f[1]=In[1]=fin[1]=1; 50 f[0]=1; 51 fin[0]=1; 52 For(i,2,1000000){ 53 In[i]=(mod-mod/i)*In[mod%i]%mod; 54 fin[i]=fin[i-1]*In[i]%mod; 55 f[i]=f[i-1]*i%mod; 56 } 57 } 58 59 long long C(long long x,long long y){ 60 if(y>x) return 0; 61 return f[x]*fin[y]%mod*fin[x-y]%mod; 62 } 63 64 int main(){ 65 in(T); 66 pre(); 67 while(T--){ 68 in(n);in(m);in(k); 69 ans=C(k+m-1,m-1); 70 for(int i=1;i<=m;i++){ 71 long long res=C(m,i)*C(k+m-1-i*n,m-1)%mod; 72 if(i%2==1) 73 ans=(ans+mod-res)%mod; 74 else 75 ans=(ans+res)%mod; 76 } 77 o(ans);p(' '); 78 } 79 return 0; 80 }