zoukankan      html  css  js  c++  java
  • CTS2019珍珠

    不难发现我们需要一个选奇数/偶数个的egf
    这个分别是 $frac {e^x - e^{-x}} {2} $ 和 $frac {e^x + e^{-x}} {2} $。

    然后就可以开始推式子了。

    答案是

    [n!sum _{k=0}^{n-2m}(frac {e^x + e^{-x}} {2}+yfrac {e^x - e^{-x}} {2})^D [x^n][y^k] ]

    [= n! frac {1}{2^D} sum _{k=0}^{n-2m} sum _{i=0}^D e^{(2i-D)x} (1+y)^i(1-y)^{D-i}[x^n][y^k] ]

    [= frac {1}{2^D} sum_{i=0}^D inom {D}{i}(2i-D)^n sum _{k=0}^{n-2m} (1+y)^i(1-y)^{D-i}[y^k] ]

    好了,考虑如何计算这个东西。

    首先将((1-y)^D)计算出来,因为$ (1+y)/(1-y) = 1 + 2y + 2y^2 + 2y^3 + ...$

    (lim = n-2m)

    我们可以轻易的算出贡献

    枚举i, 枚举有多少次是2(至少多加了1)

    有:

    [ans*2^D = sum _{i=0}^D inom {D}{i} (2i-D)^n sum_p^D ff[p] sum_{k=0}^D inom {lim-p}{k} 2^k inom{i}{k} ]

    交换第二三个和号,并且将只与一个变量相关的弄到一起,最后会形成如下形式:

    [ans*2^D = sum _{i=0}^D A(i) sum_p^D B(p) frac{1}{(i-p)!}sum_{k=0}^D C(k) frac{1}{(lim-p-k)!} ]

    其中,(A,B,C)是三个多项式

    将sigma_p后的部分当作f(p),f(p)可以通过C与(e^x)卷积得到,之后再卷积一次就能得出答案

    复杂度一个log

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod=998244353,g=3;
    inline int add(int a,int b){a+=b;return a>=mod?a-mod:a;}
    inline int sub(int a,int b){a-=b;return a<0?a+mod:a;}
    inline int mul(int a,int b){return (ll)a*b%mod;}
    inline int qpow(int a,int b){int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;}
    const int inv2=qpow(2,mod-2);
    /* math */
    typedef vector<int> poly;
    namespace poly_template{
    	int rev[4000010];
    	void DFT(int *t,int n,int type){
    		int l=0;while(1<<l<n)++l;
    		for(int i=1;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
    		for(int i=0;i<n;i++)if(i<rev[i])swap(t[i],t[rev[i]]);
    		for(int step=1;step<n;step<<=1){
    			int wn=qpow(g,(mod-1)/(step<<1));
    			for(int i=0;i<n;i+=step*2)for(int j=0,w=1;j<step;j++,w=mul(w,wn)){
    				int x=t[i+j],y=mul(w,t[i+j+step]);
    				t[i+j]=add(x,y),t[i+j+step]=sub(x,y);
    			}
    		}
    		if(type==1)return ;for(int i=1;i<n-i;i++)swap(t[i],t[n-i]);
    		int inv=qpow(n,mod-2);for(int i=0;i<n;i++)t[i]=mul(t[i],inv);
    	}
    	inline poly NTT(poly A,int n,poly B,int m){
    		poly ret;
    		int l=0;while(1<<l<n+m)++l;
    		A.resize(1<<l),B.resize(1<<l),ret.resize(1<<l);
    		DFT(&A[0],1<<l,1);DFT(&B[0],1<<l,1);
    		for(int i=0;i<1<<l;i++)ret[i]=mul(A[i],B[i]);
    		DFT(&ret[0],1<<l,-1);
    		ret.resize(n+m-1);
    		return ret;
    	}
    	inline poly NTT(poly A,poly B){return NTT(A,A.size(),B,B.size());}
    }
    using namespace poly_template;
    int D,n,m;
    
    int fac[4000010],ifac[4000010];
    inline void binom_init(int n=4000000){
    	fac[0]=ifac[0]=1;for(int i=1;i<=n;i++)fac[i]=mul(fac[i-1],i);
    	ifac[n]=qpow(fac[n],mod-2);for(int i=n-1;i;i--)ifac[i]=mul(ifac[i+1],i+1);
    }
    inline int binom(int a,int b){
    	if(b>a)return 0;
    	return mul(fac[a],mul(ifac[b],ifac[a-b]));
    }
    poly G,ff,Fac,F;
    
    int main()
    {
    	binom_init();
    	cin >> D >> n >> m;
    	if(n<2*m){printf("%d
    ",0);return 0;}
    	if(D<=n-2*m+1){printf("%d
    ",qpow(D,n));return 0;}
    	ff.resize(D+1);G.resize(D+1);Fac.resize(D+1);F.resize(D+1);
    	int lim=n-2*m;
    	for(int i=0;i<=min(D,n-2*m);i++){
    		ff[i]=binom(D,i);
    		if(i&1)ff[i]=mod-ff[i];
    		ff[i]=mul(ff[i],fac[lim-i]);
    	}
    	for(int i=0;i<=D;i++)G[i]=mul(qpow(2,i),mul(ifac[i],ifac[i])), Fac[i]=ifac[i];
    	ff=NTT(ff,Fac);
    	for(int i=0;i<=D;i++)G[i]=mul(G[i],lim-i>=0?ff[lim-i]:0);
    	for(int i=0;i<=D;i++)F[i]=mul(mul(fac[D],ifac[D-i]),qpow(1ll*(mod+2*i-D)%mod,n));
    	G=NTT(Fac,G);
    	int ans=0;
    	for(int i=0;i<=D;i++){
    		ans=add(ans,mul(F[i],G[i]));
    	}
    	ans=mul(ans,qpow(inv2,D));
    	cout << ans << endl;
    	return 0;
    }
    
    
  • 相关阅读:
    A Complete Tutorial to Learn Data Science with Python from Scratch
    OpenGL学习--08--基本渲染(灯光)
    OpenGL学习--07--模型加载(obj)
    OpenGL学习--06--键盘与鼠标交互
    OpenGL学习--05--纹理立方体--代码
    OpenGL学习--05--纹理立方体--BMP文件格式详解(转载)
    OpenGL学习—04--彩色立方体
    OpenGL学习--03--矩阵
    OpenGL学习--02--绘制一个红色三角形
    OpenGL学习--01--打开一个窗口
  • 原文地址:https://www.cnblogs.com/weiyanpeng/p/10961497.html
Copyright © 2011-2022 走看看