zoukankan      html  css  js  c++  java
  • Luogu P5408 【模板】第一类斯特林数·行

    为什么要做这题呢,当然是有用啊qwq

    首先我们考虑非常经典的式子:

    [x^{overline{n}}=sum_i left[^n_i ight] x^i ]

    然后上倍增:

    [x^{overline{2n}}=x^{overline{n}}(x+n)^{overline{n}} ]

    相当于我们已经有了一个多项式(f(x)),现在要求另一个多项式(f(x+c))

    [f(x+c)=sum_i f_i(x+c)^i ]

    [=sum_i x_isum_j f_j imes C_i^j imes c^{i-j} ]

    [=sum_i frac{x_i}{i!} sum_j j! imes f_j imesfrac{c^{i-j}}{(i-j)!} ]

    发现此时(frac{c^{i-j}}{(i-j)!})不太好处理,因此我们把它和(f)都反过来做一遍卷积然后反回去即可

    然后注意这是(nmod 2=0)的情况,(n=1)是要暴力多乘上一个((x+n))

    复杂度为(T(n)=T(n/2)+O(nlog n)=T(nlog n))

    #include<cstdio>
    #include<iostream>
    #define RI register int
    #define CI const int&
    using namespace std;
    const int N=1<<20,mod=167772161;
    int n,lim,F[N],fact[N],inv[N];
    inline int sum(CI x,CI y)
    {
    	int t=x+y; return t>=mod?t-mod:t;
    }
    inline int sub(CI x,CI y)
    {
    	int t=x-y; return t<0?t+mod:t;
    }
    inline int quick_pow(int x,int p=mod-2,int mul=1)
    {
    	for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
    }
    inline void init(CI n)
    {
    	RI i; for (fact[0]=i=1;i<=n;++i) fact[i]=1LL*fact[i-1]*i%mod;
    	for (inv[n]=quick_pow(fact[n]),i=n-1;~i;--i) inv[i]=1LL*inv[i+1]*(i+1)%mod;
    }
    namespace Poly
    {
    	int rev[N],p;
    	inline void init(CI n)
    	{
    		for (lim=1,p=0;lim<=n;lim<<=1,++p);
    		for (RI i=0;i<lim;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<p-1);
    	}
    	inline void NTT(int *f,CI opt)
    	{
    		RI i,j,k; for (i=0;i<lim;++i) if (i<rev[i]) swap(f[i],f[rev[i]]);
    		for (i=1;i<lim;i<<=1)
    		{
    			int m=i<<1,D=quick_pow(3,~opt?(mod-1)/m:mod-1-(mod-1)/m);
    			for (j=0;j<lim;j+=m)
    			{
    				int W=1; for (k=0;k<i;++k,W=1LL*W*D%mod)
    				{
    					int x=f[j+k],y=1LL*f[i+j+k]*W%mod;
    					f[j+k]=sum(x,y); f[i+j+k]=sub(x,y);
    				}
    			}
    		}
    		if (!~opt)
    		{
    			int Inv=quick_pow(lim); for (i=0;i<lim;++i) f[i]=1LL*f[i]*Inv%mod;
    		}
    	}
    	inline void convolution(int *f,CI n,CI c,int *g)
    	{
    		static int A[N],B[N]; RI i; int bs; init(n<<1);
    		for (i=0;i<n;++i) A[n-1-i]=1LL*f[i]*fact[i]%mod;
    		for (bs=1,i=0;i<n;++i,bs=1LL*bs*c%mod) B[i]=1LL*bs*inv[i]%mod;
    		for (i=n;i<lim;++i) A[i]=B[i]=0; NTT(A,1); NTT(B,1);
    		for (i=0;i<lim;++i) A[i]=1LL*A[i]*B[i]%mod;	NTT(A,-1);
    		for (i=0;i<n;++i) g[i]=1LL*A[n-1-i]*inv[i]%mod;
    	}
    	inline void solve(CI n,int *f)
    	{
    		if (!n) return (void)(f[0]=1); static int A[N],B[N];
    		RI i; int m=n>>1; solve(m,f); convolution(f,m+1,m,A);
    		for (i=0;i<=m;++i) B[i]=f[i]; for (i=m+1;i<lim;++i) A[i]=B[i]=0;
    		for (init(n),NTT(A,1),NTT(B,1),i=0;i<lim;++i) A[i]=1LL*A[i]*B[i]%mod;
    		NTT(A,-1); if (!(n&1)) for (i=0;i<=n;++i) f[i]=A[i]; else
    		for (i=0;i<=n;++i) f[i]=sum(i?A[i-1]:0,1LL*(n-1)*A[i]%mod);
    		//for (printf("%d
    ",n),i=0;i<=n;++i) printf("%d%c",f[i]," 
    "[i==n]);
    	}
    };
    int main()
    {
    	//freopen("CODE.out","w",stdout);
    	scanf("%d",&n); init(n); Poly::solve(n,F);
    	for (RI i=0;i<=n;++i) printf("%d ",F[i]); return 0;
    }
    
  • 相关阅读:
    【分布式】Zookeeper会话
    【分布式】Zookeeper客户端
    【分布式】Zookeeper序列化及通信协议
    【分布式】Zookeeper系统模型
    【分布式】Zookeeper在大型分布式系统中的应用
    【分布式】Zookeeper应用场景
    【分布式】Zookeeper使用--开源客户端
    【分布式】Zookeeper使用--Java API
    【分布式】Zookeeper使用--命令行
    【杂文】从实习到校招到工作
  • 原文地址:https://www.cnblogs.com/cjjsb/p/12044584.html
Copyright © 2011-2022 走看看