zoukankan      html  css  js  c++  java
  • 【洛谷5748】集合划分计数(多项式exp)

    点此看题面

    • (Bell_n)
    • 数据组数(le10^3)(nle10^5)

    多项式(exp)

    (i)个元素划入一个集合的方案数的(EGF)(为为F(x)),显然这些方案数都是(1),于是就有:

    [F(x)=sum_{i=1}^{+infty}frac{x^i}{i!} ]

    而我们实际上可以把它划入任意多个集合,其中划入(i)个集合的(EGF)(frac{F(x)^i}{i!})

    所以说贝尔数的(EGF)就是:

    [B(x)=sum_{i=0}^{+infty}frac{F(x)^i}{i!}=e^{F(x)} ]

    代码:(O(nlogn))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define X 998244353
    using namespace std;
    int n,m,f[N+5],g[N+5];
    I int QP(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
    int Fac[N+5],IFac[N+5];I void InitFac(CI S)
    {
    	RI i;for(Fac[0]=i=1;i<=S;++i) Fac[i]=1LL*Fac[i-1]*i%X;
    	for(IFac[i=S]=QP(Fac[S],X-2);i;--i) IFac[i-1]=1LL*IFac[i]*i%X;
    }
    namespace Poly//多项式模板
    {
    	#define PR 3
    	#define Init(n) P=1,L=0;W(P<=((n)<<1)) P<<=1,++L;for(i=0;i^P;++i) R[i]=R[i>>1]>>1|((i&1)<<L-1),A[i]=B[i]=0; 
    	int P,L,R[N<<2],A[N<<2],B[N<<2],t1[N+5],t2[N+5],t3[N+5];
    	I void NTT(int* s,CI op)
    	{
    		RI i,j,k,x,y,U,S;for(i=0;i^P;++i) i<R[i]&&(swap(s[i],s[R[i]]),0);
    		for(i=1;i^P;i<<=1) for(U=QP(QP(PR,op),(X-1)/(i<<1)),j=0;j^P;j+=i<<1) for(S=1,
    			k=0;k^i;++k,S=1LL*S*U%X) s[j+k]=((x=s[j+k])+(y=1LL*S*s[i+j+k]%X))%X,s[i+j+k]=(x-y+X)%X;
    		if(op==X-2) {RI t=QP(P,X-2);for(i=0;i^P;++i) s[i]=1LL*s[i]*t%X;}
    	}
    	I void Inv(CI n,int* a,int* b)
    	{
    		if(!n) return (void)(b[0]=QP(a[0],X-2));RI i;Inv(n>>1,a,b);
    		Init(n);for(i=0;i<=n;++i) A[i]=a[i],B[i]=b[i];NTT(A,1),NTT(B,1);
    		for(i=0;i^P;++i) A[i]=(2LL*B[i]-1LL*A[i]*B[i]%X*B[i]%X+X)%X;for(NTT(A,X-2),i=0;i<=n;++i) b[i]=A[i];
    	}
    	I void Ln(CI n,int* a,int* b)
    	{
    		RI i,j;for(i=0;i<=n;++i) b[i]=0;for(Inv(n,a,b),i=0;i^n;++i) t1[i]=1LL*a[i+1]*(i+1)%X;t1[n]=0;
    		Init(n);for(i=0;i<=n;++i) A[i]=b[i],B[i]=t1[i];NTT(A,1),NTT(B,1);
    		for(i=0;i^P;++i) A[i]=1LL*A[i]*B[i]%X;for(NTT(A,X-2),b[0]=0,i=1;i<=n;++i) b[i]=1LL*A[i-1]*QP(i,X-2)%X;
    	}
    	I void Exp(CI n,int* a,int* b)
    	{
    		if(!n) return (void)(b[0]=1);RI i;Exp(n>>1,a,b);Ln(n,b,t2);
    		Init(n);for(i=0;i<=n;++i) A[i]=b[i],B[i]=(!i-t2[i]+a[i]+X)%X;NTT(A,1),NTT(B,1);
    		for(i=0;i^P;++i) A[i]=1LL*A[i]*B[i]%X;for(NTT(A,X-2),i=0;i<=n;++i) b[i]=A[i];
    	}
    }
    int main()
    {
    	RI i;for(InitFac(N),i=1;i<=N;++i) f[i]=IFac[i];Poly::Exp(N,f,g);//构造F(x),多项式exp求出贝尔数的EGF
    	RI Tt,n;scanf("%d",&Tt);W(Tt--) scanf("%d",&n),printf("%d
    ",1LL*g[n]*Fac[n]%X);return 0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    Java基础知识(一)环境变量的设置、变量与常量、自动类型转换、自增长、赋值运算符
    ModelState
    DOM
    正则表达式常见形式
    通过JS设置一个元素的文本
    JS(三) 原型对象与原型链
    JS(二)call方法和apply方法
    第四周学习进度表
    敏捷开发方法综述
    数组02
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu5748.html
Copyright © 2011-2022 走看看