zoukankan      html  css  js  c++  java
  • LOJ6696 复读机 加强版

    Link
    考虑单个元素的EGF,显然为(f(x)=sumlimits_{ige0}[d|i]frac{x^i}{i!}=frac1dsumlimits_{i=0}^{d-1}exp(omega_d^ix))
    那么答案就是([x^n]f(x)^k)
    考虑分圆多项式(Phi_d(x)=prodlimits_{kin[0,d)wedgegcd(d,k)=1}(x-omega_d^k)=prodlimits_{k|d}(x^{frac dk}-1)^{mu(k)})
    那么(omega_d^k=(x^kmodPhi_d(x))mid_{x=omega})
    很显然(deg(Phi_d(x))=varphi(d)),且(Phi_d(x))的系数都是整数,因此(omega_d^k)可以由(omega_d^0,cdots,omega_d^{varphi(d)-1})以整数线性表示。
    实际上可以证明,对于域(mathbb N)上的线性空间(V=operatorname{span}(omega_d^0,cdots,omega_d^{d-1}))一定有(dim V=varphi(d))
    这样我们就可以把(f(x))写成(F(exp x,exp(omega x),cdots,exp(omega_d^{d-1}x)))的形式了。
    (G=F^k),那么(Ffrac{partial G}{partial x}=kGfrac{partial F}{partial x})
    由这个式子列出递推式然后解得系数是trivial的。
    时间复杂度为(O(k^{varphi(d)}log n))(log n)是快速幂的。
    (d=2)时可以通过线性筛幂函数做到(O(k))

    #include<cstdio>
    using i64=long long;
    const int N=2007,P=19491001;
    int n,k,d;i64 w,ans,fac[N],ifac[N],inv[N];
    int abs(int x){return x<0? -x:x;}
    void inc(i64&a,i64 b){a+=b-P,a+=a>>63&P;}
    i64 pow(i64 a,i64 b){i64 c=1;for(a%=P;b;b>>=1,a=a*a%P)if(b&1)c=c*a%P;return c;}
    i64 binom(int n,int m){return fac[n]*ifac[m]%P*ifac[n-m]%P;}
    void init(int n=2000)
    {
        fac[0]=ifac[0]=inv[0]=fac[1]=ifac[1]=inv[1]=1,w=pow(7,(P-1)/d);
        for(int i=2;i<=n;++i) fac[i]=i*fac[i-1]%P,inv[i]=(P-P/i)*inv[P%i]%P,ifac[i]=inv[i]*ifac[i-1]%P;
    }
    namespace Sub1
    {
        void solve()
        {
    	for(int a=0;a<=k;++a) for(int b=2-((k^a)&1);a+b<=k;b+=2) inc(ans,pow(a*w+b,n)*binom(k,(k+a+b)/2)%P*binom(k,(k+abs(a-b))/2)%P);
    	printf("%lld",4*pow(d,P-k-1)*ans%P);
        }
    }
    namespace Sub2
    {
        i64 a[N][N],b[N][N];
        void solve()
        {
    	for(int i=0;i<=k;++i) a[0][i]=a[i][0]=binom(k,i),b[i][0]=i*a[i][0]%P;
    	for(int i=1;i<=k+k;++i)
    	    for(int j=1;j<=i&&j<=k;++j)
    	    {
    		i64 x=k*a[i-1][j]-b[i-1][j]-b[i][j-1];
    		if(j>=2) x+=k*a[i-1][j-2]-b[i-1][j-2];
    		if(i>=2) x+=2*k*a[i-2][j-1]-b[i-2][j-1];
    		if(i>=2&&j>=2) x+=2*k*a[i-2][j-2]-b[i-2][j-2];
    		x=(x+4*P)%P,b[i][j]=x,a[i][j]=inv[i]*x%P;
    		if(i<=k) a[j][i]=a[i][j],b[j][i]=j*a[j][i]%P;
    	    }
    	for(int i=0;i<=k+k;++i) for(int j=0;j<=k;++j) inc(ans,(j==k? 1:2)*pow((P+i-k)*w+k-j,n)*a[i][j]%P);
    	printf("%lld",ans*pow(d,P-k-1)%P);
        }
    }
    int main()
    {
        scanf("%d%d%d",&n,&k,&d),init();
        if(n%d) puts("0"); else if(d==4) Sub1::solve(); else if(d==6) Sub2::solve();
    }
    
  • 相关阅读:
    Kafka(Go)系列(一)通过dockercompose 安装 Kafka
    grpc通过自签CA证书、server、client双向认证【支持go1.15】
    Go 基准测试和性能测试学习使用
    Debian关闭防火墙
    服务依赖开闭简单算法
    Hbase 和 Hive 的区别,各自使用场景。
    VMware虚拟机 Ubuntu1404
    安装protoc
    Redis大 key 自动过期的问题
    MySQL设置数据库为只读
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12957630.html
Copyright © 2011-2022 走看看