zoukankan      html  css  js  c++  java
  • BZOJ.4555.[HEOI2016&TJOI2016]求和(NTT 斯特林数)

    题目链接

    (Description)

    求$$sum_{i=0}^nsum_{j=0}^iS(i,j) imes 2^j imes j!mod 998244353$$

    其中(S(i,j))为第二类斯特林数((S(n,m))即在(m)个无区别盒子中放(n)个不同小球的方案数)。

    (Solution)



    (不知博客园markdowm怎么回事就是显示格式错误)

    另:第二类斯特林数 总结

    //7988kb	2340ms
    #include <cstdio>
    #include <algorithm>
    #define mod 998244353
    #define G 3
    #define invG 332748118
    #define Mod(x) x>=mod&&(x-=mod)
    typedef long long LL;
    const int N=(1<<18)+5;
    
    int pw[N],fac[N],ifac[N],inv[N],rev[N],f[N],g[N];
    
    inline int FP(int x,int k)
    {
    	int t=1;
    	for(; k; k>>=1,x=1ll*x*x%mod)
    		if(k&1) t=1ll*t*x%mod;
    	return t;
    }
    void NTT(int *a,int lim,int type)
    {
    	for(int i=1; i<lim; ++i) if(i<rev[i]) std::swap(a[i],a[rev[i]]);
    	for(int i=2; i<=lim; i<<=1)
    	{
    		int mid=i>>1;
    		int Wn=FP(~type?G:invG,(mod-1)/i);
    		for(int j=0; j<lim; j+=i)
    		{
    			int w=1,t;
    			for(int k=0; k<mid; ++k,w=1ll*w*Wn%mod)
    				a[j+k+mid]=(a[j+k]-(t=1ll*a[j+k+mid]*w%mod)+mod), Mod(a[j+k+mid]),
    				a[j+k]+=t, Mod(a[j+k]);
    		}
    	}
    	if(type==-1) for(int i=0,inv=FP(lim,mod-2); i<lim; ++i) a[i]=1ll*a[i]*inv%mod;
    }
    
    int main()
    {
    	int n; scanf("%d",&n);
    
    	pw[0]=fac[0]=1;
    	for(int i=1; i<=n; ++i)
    		pw[i]=pw[i-1]<<1, Mod(pw[i]), fac[i]=1ll*fac[i-1]*i%mod;
    
    	ifac[n]=FP(fac[n],mod-2);
    	for(int i=n-1; ~i; --i) ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
    
    	inv[1]=1;
    	for(int i=2; i<=n; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    
    	f[0]=g[0]=1, f[1]=mod-1/*not -1==*/, g[1]=n+1;
    	for(int i=2; i<=n; ++i)
    		f[i]=i&1?(mod-ifac[i]):ifac[i],
    		g[i]=1ll*(FP(i,n+1)-1)*inv[i-1]%mod*ifac[i]%mod;//FP(..,..)!=0
    
    	int len=-1,lim=1; while(lim<=n<<1) lim<<=1,++len;
    	for(int i=1; i<lim; ++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<len);
    	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);
    
    	LL ans=0;
    	for(int i=0; i<=n; ++i) ans+=1ll*pw[i]*fac[i]%mod*f[i]%mod;
    	printf("%lld
    ",ans%mod);
    
    	return 0;
    }
    
    自留
    ### $Description$
    求$$sum_{i=0}^nsum_{j=0}^iS(i,j)	imes 2^j	imes j!mod 998244353$$
    
    其中$S(i,j)$为第二类斯特林数($S(n,m)$即在$m$个无区别盒子中放$n$个不同小球的方案数)。
    ### $Solution$
    注意到$i<j$时,$S(i,j)=0$,所以$j$的上界可以到$n$。
    $$egin{aligned}sum_{i=0}^nsum_{j=0}^iS(i,j)	imes 2^j	imes j!&=sum_{i=0}^nsum_{j=0}^nS(i,j)	imes 2^j	imes j!\&=sum_{j=0}^n2^jcdot j!cdotsum_{i=0}^nS(i,j)	ag !end{aligned}$$
    
    $S(n,m)$的一个公式为$$S(n,m)=frac{1}{m!}sum_{k=0}^m(-1)^kC(m,k)(m-k)^n$$
    
    即利用容斥,枚举强制为空的盒子有多少个(空盒子至少有多少个)。因为盒子无序所以再除以$m!$。然后可以化简。$$egin{aligned}S(n,m)&=frac{1}{m!}sum_{k=0}^m(-1)^kC(m,k)(m-k)^n\&=sum_{k=0}^m(-1)^kfrac{1}{k!(m-k)!}(m-k)^n\&=sum_{k=1}^mfrac{(-1)^k}{k!}cdotfrac{(m-k)^n}{(m-k)!}end{aligned}$$
    
    注意到这是个卷积形式,所以我们可以$O(nlog n)$计算出$S(n,i)$。
    当然本题还是把上式代回去。$$egin{aligned}sum_{j=0}^n2^jcdot j!cdotsum_{i=0}^nS(i,j)&=sum_{j=0}^n2^jcdot j!cdotsum_{i=0}^nsum_{k=0}^jfrac{(-1)^k}{k!}cdotfrac{(j-k)^i}{(j-k)!}\&=sum_{j=0}^n2^jcdot j!cdotsum_{k=0}^jfrac{(-1)^k}{k!}cdotfrac{sum_{i=0}^n(j-k)^i}{(j-k)!}	ag !end{aligned}$$
    
    注意到后面还是个卷积形式,令$f(x)=frac{(-1)^x}{x!},g(x)=frac{sum_{i=0}^nx^i}{x!}$。
    设$S_n=sum_{i=0}^nx^i$,则$xS_n=sum_{i=1}^{n+1}x^i$,得$S_n=frac{x^{n+1}-1}{x-1}$,即$g(x)=frac{x^{n+1}-1}{(x-1)x!}	ag !$。特殊的,令$g(0)=1,g(1)=n+1$。
    这样$f,g$都可以递推。
    然后$$Ans=sum_{j=0}^n2^jcdot j!cdot(f*g)(j)$$
    
    NTT就行了。
    
  • 相关阅读:
    docker重启提示已存在一个容器的问题处理
    conda虚拟环境安装
    dell5460笔记本电脑ubuntu18.04系统音频驱动的安装和使用
    CentOS8的网络管理变化
    jupyter notebook 安装扩展nbextensions
    win10系统systeminfo命令的过滤用法
    《学习scrapy框架爬小说》的进一步完善
    记手机端 下拉加载新数据
    记 页面使用overflow-scroll在iOS上滑动卡顿的问题
    记 判断手机号运营商function
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9715954.html
Copyright © 2011-2022 走看看