BZOJ 4555:[TJOI2016&HEOI2016]求和(第二类斯特林数+NTT)

斯特林数与多项式求和算法
本文探讨了利用斯特林数解决特定数学问题的算法实现,通过将第二类斯特林数转换为多项式形式,进而应用快速傅里叶变换(NTT)进行高效求和,最终对结果进行模运算。

题目链接


\(Description\)

\[\sum_{i=0}^n\sum_{j=0}^iS(i,j)2^jj!\]对998244353取模后的结果。

\(n<=10^5\)


\(Solution\)
\(S(i,j)\)在这里就非常碍事,怎么把它写成一个多项式的形式呢?
第二类斯特林数还有一种容斥的写法
\[S(n,m)=\frac{1}{m!}\sum_{i=0}^m(-1)^iC_m^i(m-i)^n\]
把它带到要求的式子里去
\[\sum_{i=0}^n\sum_{j=0}^i2^jj!\frac{1}{j!}\sum_{k=0}^j(-1)^k\frac{j!}{k!(j-k)!}(j-k)^i\]
\[=\sum_{j=0}^n2^jj!\sum_{k=0}^j\frac{(-1)^k}{k!}\frac{\sum_{i=0}^n(j-k)^i}{(j-k)!}\]
最后是个等比数列求和
\[\sum_{j=0}^n2^jj!\sum_{k=0}^j\frac{(-1)^k}{k!}\frac{(j-k)^{n+1}-1}{(j-k-1)(j-k)!}\]
后边的求和直接\(NTT\)做。

#include<complex>
#include<cstdio>
using namespace std;
const int mod=998244353,R=3;
const int N=3e5+7;
int n,invR;
int F[N],G[N],fac[N],finv[N],r[N];
int qread()
{
    int x=0;
    char ch=getchar();
    while(ch<'0' || ch>'9')ch=getchar();
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x;
}
int Fpow(long long b,int p)
{
    long long res=1;
    for(;p;p>>=1,b=b*b%mod)
        if(p&1)res=res*b%mod;
    return res;
}
void NTT(int *a,int lim,int opt)
{
    for(int i=1;i<lim;i++)
        if(i<r[i])swap(a[i],a[r[i]]);
    for(int i=2;i<=lim;i<<=1)
    {
        int mid=i>>1,Wn=Fpow(~opt?R:invR,(mod-1)/i),t;
        for(int j=0;j<lim;j+=i)
        {
            long long w=1;
            for(int k=j;k<j+mid;k++,w=w*Wn%mod)
            {
                t=1ll*w*a[k+mid]%mod;
                a[k+mid]=(a[k]-t+mod)%mod;a[k]=(a[k]+t)%mod;
            }
        }
    }
    if(opt==-1)for(int i=0,inv=Fpow(lim,mod-2);i<lim;i++)a[i]=1ll*a[i]*inv%mod;
}
int main()
{
    scanf("%d",&n);
    fac[0]=finv[0]=1;
    for(int i=1;i<=n;i++)
        fac[i]=1ll*fac[i-1]*i%mod;
    finv[n]=Fpow(fac[n],mod-2);
    for(int i=n-1;i;i--)
        finv[i]=1ll*finv[i+1]*(i+1)%mod;
    for(int i=2;i<=n;i++)
        F[i]=1ll*(Fpow(i,n+1)-1)*Fpow(i-1,mod-2)%mod*finv[i]%mod;
    F[0]=1;F[1]=n+1;
    for(int i=0;i<=n;i++)
        G[i]=((i&1?-1:1)*finv[i]+mod)%mod;
    int lim=1,l=-1;
    invR=Fpow(R,mod-2);
    while(lim<=n+n)lim<<=1,l++;
    for(int i=1;i<lim;i++)r[i]=(r[i>>1]>>1)|((i&1)<<l);
    NTT(F,lim,1);NTT(G,lim,1);
    for(int i=0;i<lim;i++)
        F[i]=1ll*F[i]*G[i]%mod;
    NTT(F,lim,-1);
    int ans=0;
    for(int i=0,p=1;i<=n;i++,p=(p<<1)%mod)
        ans=(ans+1ll*p*fac[i]%mod*F[i]%mod)%mod;
    printf("%d\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/LeTri/p/10425479.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过学优化器加速函(MOA)和学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值