Loading

Character Encoding Gym - 102192A 生成函数求带限制的m变量和为n的方案数

Character Encoding Gym - 102192A 生成函数求带限制的m变量和为n的方案数

题意

给定\(n,m,k\)

\(m\)个数相加和为\(k\)且每个数不超过\(n\)的方案数

\[1 \leq n,m\leq10^5,0\leq k \leq10^5 \]

分析

我们写出题给的生成函数形式,注意到就是求

\[[x^k](x^0+x^1+x^2...x^n)^m \]

于是

\[(1+x+x^2...+x^n)^m = (\frac{1-x^{n}}{1-x})^m \]

对于分子可以直接二项式定理展开,对于分母用广义二项式定理

\[(\frac{1}{1-x})^m = \sum_{i=0}\binom{-m}{i}(-1)^ix^i=\sum_{i=0}\frac{-m(-m-1)...(-m-i+1)}{i!}(-1)^ix^i = \sum_{i=0}\frac{(m+i-1)!}{(m-1)!i!}x^i=\sum_{i=0}\binom{m+i-1}{i}x^i \]

于是枚举分子的每一项,计算分母对应项系数即可

代码

int iv[maxn];
int fac[maxn];

inline int C(int n,int m){
    if(n < m) return 0;
    return mul(fac[n],mul(iv[m],iv[n - m]));
}


int main(){
    fac[0] = iv[0] = 1;
    for(int i = 1;i < maxn;i++)
        fac[i] = mul(fac[i - 1],i);
    iv[maxn - 1] = ksm(fac[maxn - 1]);
    for(int i = maxn - 2;i;i--)
        iv[i] = mul(iv[i + 1],i + 1);
    int T = rd();
    while(T--){
        int n = rd();
        int m = rd();
        int k = rd();
        int ans = 0;
        for(int i = 0;i <= m;i++){
            if(i * n > k) break;
            int sign1 = i & 1;
            int p1 = sign1 ? MOD - C(m,i) : C(m,i);
            int j = k - i * n;
            if(j < 0) break;
            int p2 = C(m + j - 1,j);
            add(ans,mul(p1,p2));
        }
        printf("%d\n",ans);
    }
}
posted @ 2021-10-30 21:55  MQFLLY  阅读(66)  评论(0编辑  收藏  举报