zoukankan      html  css  js  c++  java
  • CCPC2021 广州A/CF Gym103415A

    Description

    给定 \(n,w\) 和长度为 \(n\) 的序列 \(c\),求

    \[\sum_{\sum b_i\le w}\prod_{i=1}^nb_i^{c_i} \]

    的值模 \(998244353\) 的结果

    \(n\le 10^5,w\le 10^18,\sum c\le 10^5\)

    Solution

    写出 \(\rm OGF\) 大概可以把答案写成下式并进行一定程度的和式变换

    \[\begin{aligned}Ans&=\sum_{k=0}^w[x^k]\prod_{i=1}^n\sum_{j=0}^{+\infty}j^{c_i}x^j\\ &=\sum_{k=0}^w[x^k]\prod_{i=1}^n\sum_{j=0}^{+\infty}\sum_{p=0}^{c_i}\begin{Bmatrix}c_i\\ p\end{Bmatrix}j^{\underline p}x^j\\ &=\sum_{k=0}^w[x^k]\prod_{i=1}^n\sum_{p=0}^{c_i}\begin{Bmatrix}c_i\\ p\end{Bmatrix}p!\sum_{j=0}^{+\infty}\binom jp x^j\\ &=\sum_{k=0}^w[x^k]\prod_{i=1}^n\sum_{p=0}^{c_i}\begin{Bmatrix}c_i\\ p\end{Bmatrix}p!x^p\sum_{j=0}^{+\infty}\binom {j+p}p x^j\\ &=\sum_{k=0}^w[x^k]\prod_{i=1}^n\sum_{p=0}^{c_i}\begin{Bmatrix}c_i\\ p\end{Bmatrix}p!x^p\left(\frac{1}{1-x}\right)^{p+1} \end{aligned}\]

    最后一步使用了数列 \(a_n=\binom{n+m}{m}\)\(m\) 为常数)的 \(\rm OGF\)\((\frac1{1-x})^{m+1}\),证明考虑对常数 \(m\) 归纳,使用了最基础的组合数求一行的和

    \(\frac 1{1-x}\) 看做自变量,剩下的看成多项式可以分治乘法求出多项式本身,但是别扭的是这个 \(x^p\),不过对于每个 \(p+1\) 都会配凑一个 \(p\)\(n\) 个式子累乘起来那么对于 \((\frac 1{1-x})^m\) 的项必然跟着一个 \(x^{m-n}\),找指数时对着等号最前面的 \([x^k]\)\(k\) 减就行了

    分治乘法的叶子处需要快速求第二类斯特林数一行,由于 \(\sum c_i\) 的上界是可以接受的,那么逐个快速求就行了

    剩下的工作是统计答案,考虑 \(f_px^{p-n}(\frac 1{1-x})^p\) 对某个 \(x^{r}\) 的贡献系数:现将 \(r\) 减掉 \(p-n\)\([x^{r-(p-n)}]\left(\frac{1}{1-x}\right)^p=\binom{r+n-1}{p-1}\)

    直接对着 \(r\in[0,w-(p-n)]\) 求一列和就能得到 \(\binom {w+n}p\),即 \(f_p\) 对答案的贡献

    组合数推一下就行了,不要直接算

    写题解的初衷是看网上没有题解,所以希望能给有需要的人一些帮助吧

    Code

    inline poly Mul(poly a,poly b){
        int n=a.size(),m=b.size(),lim=1;
        while(lim<=(n+m)) lim<<=1;
        NTT(a,lim,1); NTT(b,lim,1);
        rep(i,0,lim-1) ckmul(a[i],b[i]);
        NTT(a,lim,-1);
        a.resize(n+m-1);
        return a;
    }
    inline poly Get_Line(int x){
        vector<int> a,b; a.resize(x+1); b.resize(x+1);
        for(int i=0;i<=x;++i){
            if(i&1) a[i]=mod-ifac[i]; else a[i]=ifac[i];
            b[i]=mul(ifac[i],ksm(i,x));
        }
        poly vec=Mul(a,b); vec.resize(x+1);
        return vec;
    }
    inline poly solve(int l,int r){
        if(l==r){
            poly str=Get_Line(c[l]);
            poly ret; ret.resize(c[l]+2);
            rep(i,0,c[l]) ret[i+1]=mul(str[i],fac[i]);
            return ret;
        }
        int mid=(l+r)>>1;
        return Mul(solve(l,mid),solve(mid+1,r));
    }
    signed main(){
        n=5e5; fac[0]=inv[0]=1; 
        for(int i=1;i<=n;++i) fac[i]=mul(fac[i-1],i);
        ifac[n]=ksm(fac[n],mod-2);
        Down(i,n,1) ifac[i-1]=mul(ifac[i],i),inv[i]=mul(ifac[i],fac[i-1]);
        n=read(); w=read(); 
        int sumc=0;
        rep(i,1,n) sumc+=(c[i]=read());
        vector<int> f=solve(1,n);
        int ans=0,dfac=1;
        for(int i=0;i<=n+sumc;++i){
            if(i-n>w) break;
            if(i>=n){
                ckadd(ans,mul(f[i],mul(dfac,ifac[i])));
            }
            ckmul(dfac,(w+n-i)%mod);
        }
        print(ans);
        return 0;
    }
    
  • 相关阅读:
    2020软件工程作业02
    第一次作业
    伪造IP
    Windows 上安装metasploit
    Kali安装 Typora
    在linux系统中安装调用汉语打字软件
    2020 年 10 月 10 日跑步随想
    最长公共前缀
    N皇后
    一道有趣的异步题
  • 原文地址:https://www.cnblogs.com/yspm/p/15765945.html
Copyright © 2011-2022 走看看