HDU 6397 生成函数

题目链接

题意:

m个位置每个位置可以填上[0,n-1]求m个数和为k的方案数

思路:

既然用生成函数做题的话先观察题目是否是求组合数,稍微思考发现题目求的就是组合数,于是开心的列一个生成函数(1+*x^1+x^2+...+x^n)

根据题目意思可以得到此题的指数型生成函数(1+x^1+x^2+...+x^(n-1))^m,表示每个位置可以放[0,n-1]共放置m个位置

对(1+x^1+x^2+...+x^(n-1))求和,根据等比数列求和公式得到(1-x^n)/(1-x),最终式子变成(1-x^n)^m*(1-x)^(-m)

对(1-x^n)^m二项式展开得到Σ(i=0->m)C(m,i)*(-1)^i*(x^n)^i,对(1-x)^(-m)进行泰勒展开处理得到Σ(i=0->无穷)C(m+i-1,i)x^i

泰勒展开:

因为x的最终表达式是x,所以可以得出a=1,所以f(a)==f'(a)==...==f(n)(a)==1,同时系数会因为求导和阶乘的缘故变为C(m+i-1,i),所以(1-x)^(-m)的泰勒展开结果为Σ(i=0->无穷)C(m+i-1,i)x^i

最终我们需要的是x^k前的系数就是答案了,至于怎么统计就看代码了

C++代码:

#include 
using namespace std;
const int mod  = 998244353;
const int maxn = 200010;

int f[maxn],inv[maxn],n,m,k;

int C( int n , int m )
{
    return 1LL*f[n]*inv[m]%mod*inv[n-m]%mod;
}

int Qpow( int a , int b )
{
    int res = 1;
    while ( b )
    {
        if ( b&1 )
            res = 1LL*res*a%mod;
        a = 1LL*a*a%mod;
        b = b>>1;
    }
    return res;
}

int main()
{
    f[0] = inv[0] = 1;
    for ( int i = 1; i

 

你可能感兴趣的:(其他)