【题解】Luogu P4091 [HEOI2016/TJOI2016]求和

原题传送门

[egin{aligned} a n s &=sum_{i=0}^{n} sum_{j=0}^{i}left{egin{array}{c}{i} \ {j}end{array} ight} 2^{j} imes j ! \ &=sum_{i=0}^{n} sum_{j=0}^{n}left{egin{array}{c}{i} \ {j}end{array} ight} 2^{j} imes j ! \ &=sum_{j=0}^{n} 2^{j} imes j ! sum_{i=0}^{n}left{egin{array}{c}{i} \ {j}end{array} ight} \ &=sum_{j=0}^{n} 2^{j} imes j ! sum_{i=0}^n(frac{1}{j !} sum_{k=0}^j(-1)^k binom{j}{k} (j-k)^i) \ &=sum_{j=0}^{n} 2^{j} imes j ! sum_{i=0}^{n} sum_{k=0}^{j} frac{(-1)^{k}}{k !} cdot frac{(j-k)^{i}}{(j-k) !} \ &=sum_{j=0}^{n} 2^{j} imes j ! sum_{k=0}^{j} frac{(-1)^{k}}{k !} cdot frac{(j-k)^{n+1}-1}{(j-k-1)(j-k) !} end{aligned}]

这就是一个很明显的卷积形式,NTT求一下即可

要注意一下最后一步,因为用了等比数列求和,所以(1)要特判

#include <bits/stdc++.h>
#define N 100005
#define mod 998244353
#define G 3
#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
inline int power(register int a,register int b)
{
    int res=1;
    while(b)
    {
        if(b&1)
            res=1ll*res*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return res;
}
int n,fac[N],invf[N],f[N<<2],g[N<<2],R[N<<2],ans;
inline void NTT(register int *a,register int n,register int f)
{
    for(register int i=0;i<n;++i)
        if(i<R[i])
            swap(a[i],a[R[i]]);
    for(register int i=1;i<n;i<<=1)
    {
        int T=power(G,(mod-1)/(i<<1));
        if(f==-1)
            T=power(T,mod-2);
        for(register int j=0;j<n;j+=(i<<1))
        {
            int t=1;
            for(register int k=0;k<i;++k,t=1ll*t*T%mod)
            {
                int Nx=a[j+k],Ny=1ll*t*a[i+j+k]%mod;
                a[j+k]=(0ll+Nx+Ny)%mod;
                a[i+j+k]=(0ll+Nx-Ny+mod)%mod;
            }
        }
    }
}
int main()
{
    n=read();
    fac[0]=fac[1]=1;
    for(register int i=2;i<=n;++i)
        fac[i]=1ll*fac[i-1]*i%mod;
    invf[n]=power(fac[n],mod-2);
    for(register int i=n-1;i>=0;--i)
        invf[i]=1ll*invf[i+1]*(i+1)%mod;
    for(register int i=0;i<=n;++i)
        f[i]=1ll*(i&1?mod-1:1)*invf[i]%mod;
    for(register int i=0;i<=n;++i)
        g[i]=1ll*(power(i,n+1)+mod-1)*power(i-1<0?i+mod-1:i-1,mod-2)%mod*invf[i]%mod;
    g[1]=n+1;
    int lim=1,ct=0;
    while(lim<n<<1)
        lim<<=1,++ct;
    for(register int i=0;i<lim;++i)
        R[i]=(R[i>>1]>>1)|((i&1)<<(ct-1));
    NTT(f,lim,1),NTT(g,lim,1);
    for(register int i=0;i<lim;++i)
        f[i]=1ll*f[i]*g[i]%mod;
    NTT(f,lim,-1);
    int inv=power(lim,mod-2);
    for(register int i=0;i<=n;++i)
        ans=(0ll+ans+1ll*power(2,i)*fac[i]%mod*f[i]%mod*inv%mod)%mod;
    write(ans);
	return 0;
}
原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/11318938.html