• Luogu P5296 [北京省选集训2019]生成树计数


    Link

    Kirchhoff定理是没办法处理生成树的权值为边权和的情况的,因此考虑将其转化为边权积的形式。

    [(sumlimits_{i=1}^na_i)^k=k![x^k]exp((sumlimits_{i=1}^na_i)x)=k![x^k]prodlimits_{i=1}^nexp(a_ix) ]

    那么我们将一条边((u,v,w))的边权视作(exp(wx))即可。
    因为我们只需要求(x^k)的系数,因此计算过程中可以全程对(x^{k+1})取模。

    #include<cctype>
    #include<cstdio>
    #include<cstring>
    using i64=long long;
    const int N=37,P=998244353;
    int n,k;i64 fac[N],ifac[N],e[N][N],g[N][N][N],ans[N];
    void inc(i64&a,i64 b){a+=b-P,a+=a>>63&P;}
    void dec(i64&a,i64 b){a-=b,a+=a>>63&P;}
    i64 pow(i64 a,i64 b){i64 r=1;for(;b;b>>=1,a=a*a%P)if(b&1)r=r*a%P;return r;}
    int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
    void add(int u,int v)
    {
        i64 pw=1,x;
        for(int i=0;i<=k;++i,pw=pw*e[u][v]%P)
    	x=pw*ifac[i]%P,dec(g[u][v][i],x),dec(g[v][u][i],x),inc(g[u][u][i],x),inc(g[v][v][i],x);
    }
    void mul(i64*a,i64*b,i64*c)
    {
        static i64 t[N];memset(t,0,8*k+8);
        for(int i=0;i<=k;++i) for(int j=0;i+j<=k;++j) (t[i+j]+=a[i]*b[j])%=P;
        memcpy(c,t,8*k+8);
    }
    void inv(i64*a,i64*c)
    {
        static i64 b[N],t[N];memset(t+1,0,8*k),t[0]=pow(a[0],P-2);
        for(int i=1;i<=k;++i) b[i]=a[i]*t[0]%P;
        for(int i=1;i<=k;++i) for(int j=1;j<=i;++j) (t[i]+=(P-b[j])*t[i-j])%=P;
        memcpy(c,t,8*k+8);
    }
    int main()
    {
        n=read(),k=read(),fac[0]=ifac[0]=1;
        for(int i=1;i<=k;++i) ifac[i]=pow(fac[i]=i*fac[i-1]%P,P-2);
        for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) e[i][j]=read();
        for(int i=1;i<=n;++i) for(int j=1;j<i;++j) add(i,j);
        ans[0]=1,--n;
        for (int i=1;i<=n;++i)
        {
    	static i64 tmp[N];
    	mul(g[i][i],ans,ans),inv(g[i][i],tmp);
    	for(int j=n;j>=i;--j) mul(g[i][j],tmp,g[i][j]);
    	memset(g[i][i],0,8*k+8),g[i][i][0]=1;
    	for(int u=n;u^i;--u)
    	    for(int v=n;v>=i;--v)
    	    {
    		mul(g[i][v],g[u][i],tmp);
    		for(int j=0;j<=k;++j) dec(g[u][v][j],tmp[j]);
    	    }
        }
        printf("%lld",ans[k]*fac[k]%P);
    }
    
  • 相关阅读:
    beta冲刺————第二天(2/5)
    beta冲刺————第一天(1/5)
    个人作业——软件产品案例分析
    c++第七次作业____最后的总结
    计算器图形界面
    object-oriented second work
    第五次作业(文件处理)
    object-oriented first work
    第四次作业--计算器简单计算
    新的Calculator的规范作业
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12969305.html
Copyright © 2020-2023  润新知