题解 P5850【calc 加强版】

$\text{Link}$

题意

对 $n\in[1,m]$ 求

$$\sum_{a_{1,\cdots n}\in[1,k],a_i\ne a_j(1\le i<j\le n)}\prod_{i=1}^n a_i$$

对 $998244353$ 取模。

$m\le 5\times 10^5$,$k<998244353$.

思路

考虑这个式子的意义,先不考虑数列的顺序,写出答案的 $\text{OGF }F(x)$。

不难发现

$$F(x)=\prod_{i=1}^k(1+ix)$$

这个先考虑 $\ln$ 后转成加法。

$$\begin{aligned}F(x)&=\exp\left(\sum_{i=1}^k\ln(1+ix)\right)\\\end{aligned}$$

我们知道:

$$\ln(1-x)=-\sum_{i=1}^{n}\frac{x^i}i$$

$$\begin{aligned}F(x)&=\exp\left(\sum_{i=1}^k\ln(1+ix)\right)\\&=\exp\left(-\sum_{i=1}^k\sum_{j=1}^n\frac{(-ix)^j}j\right)\\&=\exp\left(\sum_{j=1}^n\frac{(-1)^{j+1}}{j}x^j\sum_{i=1}^ki^j\right)\end{aligned}$$ 现在要求 $j\in[1,n]$ 的自然数幂和。令它的 $\text{EGF}$ 为 $G(x)$:

$$\begin{aligned}G(x)&=\sum_{i=0}^n\dfrac{x^i}{i!}\sum_{j=1}^kj^i\\&=\sum_{j=1}^k\sum_{i=0}^n\dfrac{(jx)^i}{i!}\\&=\sum_{j=1}^ke^{jx}\\&=\dfrac{e^{x(k+1)}-e^x}{e^x-1}\end{aligned}$$

分子分母常数都是 $0$,同除 $x$ 就好了。

注意 $\text{EGF}$ 乘上 $i!$。

注意答案乘上 $n!$。

时间复杂度 $\Theta(n\log n)$。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
namespace IO{//by cyffff

}
const int N=1048576+10,mod=998244353,inv2=mod+1>>1;
namespace Init{
    int fac[N],ifac[N],inv[N],G[21][N];
    inline int qpow(int x,int y){
        int res=1;
        while(y){
            if(y&1) res=1ll*res*x%mod;
            x=1ll*x*x%mod;
            y>>=1;
        }
        return res;
    }
    inline void getG(){
        for(int i=0;i<21;i++){
            int *P=G[i],W=1<<i;
            P[0]=1;
            P[1]=qpow(3,(mod-1)/(1<<i+1));
            const int tmp=P[1];
            for(int j=2;j<W;j++)
                P[j]=1ll*P[j-1]*tmp%mod;
        }
    }
    inline void Prefix(int L){
        fac[0]=1;
        for(int i=1;i<=L;i++)
            fac[i]=1ll*fac[i-1]*i%mod;
        ifac[L]=qpow(fac[L],mod-2);
        for(int i=L;i>=1;i--)
            ifac[i-1]=1ll*ifac[i]*i%mod;
        for(int i=1;i<=L;i++)
            inv[i]=1ll*ifac[i]*fac[i-1]%mod;
    }
}
using namespace Init;
namespace Poly{
    int lim,rev[N];
    int F[N],G[N],H[N];
    int T1[N],T2[N],T3[N];
    inline void init(int n,int mode=1){
        if(mode){
            int l=0;
            for(lim=1;lim<=n;lim<<=1)l++;
            for(int i=1;i<lim;i++)
                rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
        }else{
            for(lim=1;lim<=n;lim<<=1);
        }
    }
    inline void NTT(int *a,int T){
        for(int i=0;i<lim;i++)
            if(i<rev[i])
                swap(a[i],a[rev[i]]);
        for(int i=1,o=0;i<lim;i<<=1,o++){
            const int *P=::G[o];
            for(int j=0;j<lim;j+=(i<<1)){
                int t1,t2;
                for(int k=0;k<i;k++){
                    t1=a[j+k];
                    t2=1ll*P[k]*a[i+j+k]%mod;
                    a[j+k]=(t1+t2)%mod;
                    a[i+j+k]=(t1-t2+mod)%mod;
                }
            }
        }
        if(T==1) return ;
        int Inv=qpow(lim,mod-2);
        reverse(a+1,a+lim);
        for(int i=0;i<lim;i++)
            a[i]=1ll*a[i]*Inv%mod;
    }
    inline void Mul(int *a,int *b){
        for(int i=0;i<lim;i++)
            F[i]=b[i];
        NTT(a,1),NTT(F,1);
        for(int i=0;i<lim;i++)
            a[i]=1ll*a[i]*F[i]%mod;
        NTT(a,-1);
    }
    inline void Sqr(int *a,int *b){
        static int F[N];
        for(int i=0;i<lim;i++)
            F[i]=a[i];
        NTT(F,1);
        for(int i=0;i<lim;i++)
            b[i]=1ll*F[i]*F[i]%mod;
        NTT(b,-1);
    }
    inline void Inv(int *a,int *b,int n){
        static int T4[N];
        if(n==1){
            b[0]=qpow(a[0],mod-2);
            return ;
        }
        Inv(a,b,n+1>>1);
        init(n<<1);
        for(int i=0;i<n;i++)
            T4[i]=a[i];
        for(int i=n;i<lim;i++)
            T4[i]=0;
        NTT(b,1),NTT(T4,1);
        for(int i=0;i<lim;i++)
            b[i]=1ll*b[i]*(2-1ll*b[i]*T4[i]%mod+mod)%mod;
        NTT(b,-1);
        for(int i=n;i<lim;i++)
            b[i]=0;
    }
    inline void Der(int *a,int *b,int n){
        for(int i=1;i<n;i++)
            b[i-1]=1ll*i*a[i]%mod;
        b[n-1]=0;
    }
    inline void Int(int *a,int *b,int n){
        for(int i=1;i<n;i++)
            b[i]=1ll*a[i-1]*inv[i]%mod;
        b[0]=0;
    }
    inline void Log(int *a,int *b,int n){
        for(int i=0;i<lim;i++)
            T1[i]=T2[i]=0;
        Der(a,T1,n);
        Inv(a,T2,n);
        Mul(T1,T2);
        Int(T1,b,n);
    }
    inline void Exp(int *a,int *b,int n){
        if(n==1){
            b[0]=1;
            return ;
        }
        Exp(a,b,n+1>>1);
        init(n<<1,0);
        for(int i=0;i<lim;i++)
            T3[i]=0;
        Log(b,T3,n);
        for(int i=0;i<n;i++)
            T3[i]=(a[i]-T3[i]+mod)%mod;
        for(int i=n;i<lim;i++)
            b[i]=T3[i]=0;
        T3[0]++;
        Mul(b,T3); 
        for(int i=n;i<lim;i++)
            b[i]=0;
    }
    inline void QPow(int *a,int *b,int n,int k1,int k2){//k1:mod p;k2:mod φ(p) 
        static int T4[N],T5[N];
        int fir=0;
        for(;fir<n&&!a[fir];fir++);
        if(1ll*fir*k1>=n){
            for(int i=0;i<n;i++)
                b[i]=0;
            return ;
        }
        const int invf=qpow(a[fir],mod-2);
        const int powf=qpow(a[fir],k2);
        for(int i=0;i<n;i++)
            a[i]=1ll*a[i+fir]*invf%mod;
        Log(a,T4,n);
        for(int i=0;i<n;i++)
            a[i]=1ll*T4[i]*k1%mod;
        Exp(a,T5,n);
        fir*=k1;
        for(int i=0;i<fir;i++)
            b[i]=0;
        for(int i=fir;i<n;i++)
            b[i]=1ll*T5[i-fir]*powf%mod;
    }
    inline void Sqrt(int *a,int *b,int n){
        static int T4[N],T5[N];
        if(n==1){
            b[0]=1;
            return ;
        }
        Sqrt(a,b,n+1>>1);
        init(n<<1);
        for(int i=0;i<lim;i++)
            T4[i]=T5[i]=G[i]=0;
        for(int i=0;i<n;i++)
            T5[i]=a[i];
        Inv(b,T4,n);
        Mul(T4,T5);
        for(int i=0;i<n;i++)
            b[i]=1ll*inv2*(b[i]+T4[i])%mod;
        for(int i=n;i<lim;i++)
            b[i]=0;
    }
}
int k,n;
int T1[N],T2[N],T3[N],T4[N],T5[N];
inline void solve(int n){
    for(int i=1;i<n;i++)
        T1[i-1]=(1ll*(qpow(k+1,i)-1)*ifac[i])%mod,
        T2[i-1]=ifac[i];
    Poly::Inv(T2,T3,n);
    Poly::Mul(T1,T3);
    for(int i=0;i<n;i++)
        T1[i]=1ll*T1[i]*fac[i]%mod;
    for(int i=1;i<n;i++){
        int tmp=1ll*T1[i]*inv[i]%mod;
        if(i+1&1) T4[i]=mod-tmp;
        else T4[i]=tmp;
    }
    Poly::Exp(T4,T5,n);
    for(int i=0;i<n;i++)
        T5[i]=1ll*T5[i]*fac[i]%mod;
}
int main(){
    k=read(),n=read()+1;
    getG();
    Prefix(n+10);
    solve(n+10);
    for(int i=1;i<n;i++)
        write(T5[i]),putc('\n');
    flush();
}

再见 qwq~

posted @ 2021-12-15 17:53  ffffyc  阅读(2)  评论(0编辑  收藏  举报  来源