[TJOI/HEOI2016] 求和 题解

为什么又是佳媛姐姐啊啊啊!


斯特林数在这道题中不好处理,直接拆开:

\[f(n)=\sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix}i\\j\end{Bmatrix}2^jj! \]

\[=\sum_{j=0}^n2^jj!\sum_{i=0}^n\sum_{k=0}^j\frac{(-1)^k(j-k)^i}{k!(j-k)!} \]

\[=\sum_{j=0}^n2^jj!\sum_{k=0}^j\frac{(-1)^k\sum\limits_{i=0}^n(j-k)^i}{k!(j-k)!} \]

单独考虑后半部分。设 \(f(i)=\dfrac{(-1)^i}{i!},g(i)=\dfrac{\sum\limits_{k=0}^n i^k}{i!}=\dfrac{[i\ne 1](\dfrac{i^{n+1}-1}{i-1})+[i=1](n+1)}{i!}\)

那么答案即为:

\[\sum_{j=0}^n2^jj!(f\times g)(j) \]

NTT求解,时间复杂度 \(O(n\log n)\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+5,p=998244353;
namespace NTT{
    int rev[N],mx,k,m,qp,h;
    struct dft{int fg[N];};
    int qpow(int x,int y){
        int re=1;
        while(y){
            if(y&1) re=re*x%p;
            x=x*x%p,y>>=1;
        }return re;
    }void init(int n){
        mx=1,k=0,rev[0]=0,h=m-1;
        while(mx<=n) mx*=2,k++;
        for(int i=0;i<mx;i++)
            rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
        qp=qpow(mx,p-2);
    }void fmd(dft &a){
        for(int i=m-1;i<mx;i++) if(a.fg[i])
            a.fg[i%h]=(a.fg[i%h]+a.fg[i])%p,a.fg[i]=0;
    }void ntt(dft &a,int fl){
        for(int i=0;i<mx;i++)
            if(i<rev[i]) swap(a.fg[i],a.fg[rev[i]]);
        for(int i=1;i<mx;i*=2){
            int om=qpow(fl?3:(p+1)/3,(p-1)/(i<<1));
            for(int j=0,w=1;j<mx;j+=i*2,w=1)
                for(int k=j;k<j+i;k++,w=w*om%p){
                    int x=a.fg[k],y=w*a.fg[k+i]%p;
                    a.fg[k]=(x+y)%p,a.fg[k+i]=(x-y+p)%p;
                }
        }if(fl) return;
        for(int i=0;i<mx;i++)
            a.fg[i]=a.fg[i]*qp%p;
    }
}using namespace NTT;
int n;dft f,g;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n,init(n*2+1);
    for(int i=0,sum,jc=1;i<=n;i++,jc=jc*i%p){
        f.fg[i]=qpow(jc,p-2)*(1-i%2*2);
        g.fg[i]=(qpow(i,n+1)-1)*qpow((i-1)*jc%p,p-2)%p;
        if(i==1) g.fg[i]=(n+1)*jc%p;
    }ntt(f,1),ntt(g,1);
    for(int i=0;i<mx;i++)
        f.fg[i]=f.fg[i]*g.fg[i]%p;
    ntt(f,0);int ans=0;
    for(int i=0,jc=1;i<=n;i++,jc=jc*i%p)
        ans=(ans+qpow(2,i)*jc%p*f.fg[i])%p;
    cout<<ans;
    return 0;
}
posted @   长安一片月_22  阅读(4)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示