• [多项式下降幂][组合][二项式定理]luogu P6620 [省选联考 2020 A 卷] 组合数问题


    题面

    https://www.luogu.com.cn/problem/P6620

    求 $(\sum_{k=0}^n f(k) \times x^k \times \binom{n}{k})mod\space P$

    其中 $f(k)$ 是给定的 m 次多项式

    分析

     这种多项式放在乘积里的有两种思路,一种是拆单项,另一种是转下降幂/上升幂

    这题后面还有个 k 相关的组合数,果断转下降幂了,假设转好的下降幂多项式为 $g(x)=\sum_{i=0}^m b_i x^{\underline{i}}$

    由 $x^i=\sum_{j=0}^i \begin{Bmatrix}i\\j\end{Bmatrix} x^{\underline{j}}$ 得

    $f(x)=\sum_{i=0}^m a_i x^i = \sum_{i=0}^m a_i \sum_{j=0}^i \begin{Bmatrix}i\\j\end{Bmatrix} x^{\underline{j}}$

    $f(x)=\sum_{j=0}^m x^{\underline{j}} \sum_{i=j}^m \begin{Bmatrix}i\\j\end{Bmatrix} a_i$

    即 $b_i=\sum_{j=i}^m \begin{Bmatrix}j\\i\end{Bmatrix} a_j$

    原式变为 $\sum_{k=0}^n \sum_{i=0}^m b_i k^{\underline{i}} x^k \binom{n}{k}$

    $\sum_{i=0}^m b_i \sum_{k=0}^n k^{\underline{i}} x^k \binom{n}{k}$

    对于下降幂和组合数,有

    $k^{\underline{m}} \binom{n}{k}=n^{\underline{m}} \binom{n-m}{k-m}$ 

    用组合数通项与下降幂公式易证

    则 $\sum_{i=0}^m b_i \sum_{k=0}^n x^k n^{\underline{i}} \binom{n-i}{k-i}$

    把 $n^{\underline{i}}$ 整理到前面

    $\sum_{i=0}^m b_i n^{\underline{i}} \sum_{k=0}^n x^k \binom{n-i}{k-i}$

    将枚举 k 改为枚举 k-i

    $\sum_{i=0}^m b_i n^{\underline{i}} \sum_{k=0}^{n-i} x^{k+i} \binom{n-i}{k}$

    $\sum_{i=0}^m b_i n^{\underline{i}} x^i \sum_{k=0}^{n-i} x^k \binom{n-i}{k}$

    易发现二项式定理的形式

    $\sum_{i=0}^m b_i n^{\underline{i}} x^i (x+1)^{n-i}$

    这就是最终式子了,预处理出来就只需要 $O(m)$ 统计答案,加上斯特林数暴力递推转下降幂 $O(m^2)$

    代码

    #include <iostream>
    #include <cstdio>
    using namespace std;
    typedef long long ll;
    const int N=1e3+10;
    int n,m;
    ll S[N][N],dexp[N],p,b[N],a[N],x[N],x_1[N],ans;
    
    ll Pow(ll x,ll y) {ll ans=1;for (;y;y>>=1,x=x*x%p) if (y&1) ans=ans*x%p;return ans;}
    
    int main() {
        scanf("%d%lld%lld%d",&n,&x[1],&p,&m);
        for (int i=0;i<=m;i++) scanf("%lld",&a[i]);
        S[0][0]=1;
        for (int i=1;i<=m;i++)
            for (int j=0;j<=i;j++)
                S[i][j]=(S[i-1][j]*j%p+(j?S[i-1][j-1]:0))%p;
        x[0]=dexp[0]=1;dexp[1]=n;
        for (int i=2;i<=m;i++) x[i]=x[i-1]*x[1]%p,dexp[i]=dexp[i-1]*(n-i+1)%p;
        x_1[m]=Pow(x[1]+1,n-m);
        for (int i=m-1;~i;i--) x_1[i]=x_1[i+1]*(x[1]+1)%p;
        for (int j=0;j<=m;j++)
            for (int i=j;i<=m;i++) (b[j]+=S[i][j]*a[i]%p)%=p;
        for (int i=0;i<=min(m,n);i++) (ans+=b[i]*dexp[i]%p*x[i]%p*x_1[i]%p)%=p;
        printf("%lld",ans);
    }
    View Code
  • 相关阅读:
    《代码大全》阅读心得一
    vi列模式
    以指定的概率/机会获取元素
    自用VIM配置
    优雅的Javascript
    关于遮罩层
    CSS3属性BorderRadius详解[圆角]
    CSS3属性boxshadow详解[盒子阴影]
    CSS3文字特效
    Css3 Animation详解
  • 原文地址:https://www.cnblogs.com/vagari/p/14608390.html
Copyright © 2020-2023  润新知