zoukankan      html  css  js  c++  java
  • 【洛谷5409】第一类斯特林数·列

    点此看题面

    • 给定(n,m),对于所有(i=0sim n),求出(S_2(i,m))
    • (n,m<131072)

    第一类斯特林数·列

    考虑单独一个置换环,可以构造出第一列第一类斯特林数的指数型生成函数

    [F(x)=sum_{i=1}^n(i-1)!frac{x^i}{i!}=sum_{i=1}^nfrac1ix^i ]

    现在我们需要(m)个置换环,相当于是选出(m)个置换环拼在一起,然后除以(m!)去掉环的顺序,也就是说答案的指数型生成函数就应该是:

    [frac{F(x)^m}{m!} ]

    这里涉及到多项式快速幂,注意(F(x))的第(0)项为(0),第(1)项为(1),因此我们先拿走第(0)项,最后在开头添上(m)(0)即可。

    代码:(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 131072
    #define X 167772161
    using namespace std;
    int n,m,f[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];
    	}
    	I void Pow(CI n,int* a,CI k)
    	{
    		Ln(n,a,t3);for(RI i=0;i<=n;++i) t3[i]=1LL*t3[i]*k%X,a[i]=0;Exp(n,t3,a);
    	}
    }
    int main()
    {
    	RI i;for(scanf("%d%d",&n,&m),InitFac(n),i=0;i^n;++i) f[i]=QP(i+1,X-2);//求出第一列除去原第0项的指数型生成函数
    	for(Poly::Pow(n-1,f,m),i=0;i<=min(n,m-1);++i) printf("0 ");//求出F(x)^m,在开头添m个0
    	for(i=0;i<=n-m;++i) printf("%d ",1LL*f[i]*IFac[m]%X*Fac[i+m]%X);return 0;//除以m!去掉环的顺序,由于是EGF答案要乘(i+m)!
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    day25:接口类和抽象类
    vue1
    How the weather influences your mood?
    机器学习实验方法与原理
    How human activities damage the environment
    Slow food
    Brief Introduction to Esports
    Massive open online course (MOOC)
    Online learning in higher education
    Tensorflow Dataset API
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/S1_L.html
Copyright © 2011-2022 走看看