zoukankan      html  css  js  c++  java
  • 【CF917D】Stranger Trees

    题目

    看题解的时候才突然发现(zky)讲过这道题啊,我现在怕不是一个老年人了

    众所周知矩阵树求得是这个

    [sum_{T}prod_{ein T}w_e ]

    而我们现在的这个问题有些鬼畜了,给定一棵树,求和这棵树有(k)条公共边的生成树个数

    我们如何区分出和原生成树有几条边呢,容斥显然不是很可做,于是之后就不会啦

    看了题解发现这是神仙题,引用潮子名言我可能这辈子是做不出来了

    对于不在给定生成树里的边(w_e)我们设(w_e=1),对于在生成树里的边我们将其设成(w_e=x),没错就是(x),就是一个多项式

    这样矩阵树得到的结果必然也是一个多项式,其中(k)次项系数就对应了和原树有(k)条公共边的方案数

    如果模数是(NTT)模数那么我们直接矩阵树套多项式就好啦,但是(O(n^4logn))的复杂度显然不科学啊

    考虑一些其他求多项式系数的方法,暴力一点也行

    于是我们可以高斯消元

    这个多项式是一个(n-1)的多项式,于是我们可以直接给(x)(n)种取值,之后得到(n)个方程,之后高斯消元就可以求出系数来了

    代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define re register
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    const int maxn=105;
    const int mod=1e9+7;
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    int n,x[maxn],y[maxn],ans[maxn];
    int a[maxn][maxn],b[maxn][maxn];
    inline int ksm(int a,int b) {
    	int S=1;
    	while(b) {if(b&1) S=(1ll*S*a)%mod;b>>=1;a=(1ll*a*a)%mod;}
    	return S;
    }
    inline void reBuild() {
    	for(re int i=1;i<=n;i++) a[i][i]=n-1;
    	for(re int i=1;i<=n;i++)
    		for(re int j=1;j<=n;j++) {
    			if(i==j) continue;
    			a[i][j]=mod-1;
    		}
    }
    inline int solve(int t) {
    	reBuild();
    	for(re int i=1;i<n;i++) {
    		int u=x[i],v=y[i];
    		a[u][u]--,a[v][v]--;
    		a[u][u]+=t,a[v][v]+=t;
    		a[u][v]=a[v][u]=mod-t;
    	}
    	int o=0;
    	for(re int i=1;i<n;i++) {
    		int p;
    		for(p=i;p<n;++p) if(a[p][i]) break;
    		if(p!=i) std::swap(a[p],a[i]),o^=1;
    		int Inv=ksm(a[i][i],mod-2);
    		for(re int j=i+1;j<n;j++) {
    			int mul=(1ll*a[j][i]*Inv)%mod;
    			for(re int k=i;k<n;k++)
    				a[j][k]=(a[j][k]-1ll*a[i][k]*mul%mod+mod)%mod;
    		}
    	}
    	int now=1;
    	for(re int i=1;i<n;i++) now=(1ll*now*a[i][i])%mod;
    	return o?(mod-now)%mod:now;
    }
    int main() {
    	n=read();
    	for(re int i=1;i<n;i++) x[i]=read(),y[i]=read();
    	for(re int i=0;i<n;i++) {
    		b[i][n]=solve(i+1);
    		b[i][0]=1;
    		for(re int j=1;j<n;j++) b[i][j]=ksm(i+1,j);
    	}
    	for(re int i=0;i<n;i++) {
    		int p;
    		for(p=i;p<n;++p) if(b[p][i]) break;
    		if(p!=i) std::swap(b[p],b[i]);
    		int Inv=ksm(b[i][i],mod-2);
    		for(re int j=n;j>=i;--j) b[i][j]=(1ll*b[i][j]*Inv)%mod;
    		for(re int j=i+1;j<n;j++)
    			for(re int k=n;k>=i;--k)
    				b[j][k]=(b[j][k]-1ll*b[j][i]*b[i][k]%mod+mod)%mod;
    	}
    	ans[n-1]=b[n-1][n];
    	for(re int i=n-2;i>=0;--i) {
    		ans[i]=b[i][n];
    		for(re int j=n-1;j>i;--j)
    			ans[i]=(ans[i]-1ll*ans[j]*b[i][j]%mod+mod)%mod;
    	}
    	for(re int i=0;i<n;i++) printf("%d ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    用Actionscript3.0编写的伪3D文字旋转
    iis权限设置
    SQL 不能通过IP正常连接终极解决方案
    创建一个非常简单的NHibernate的应用
    解决“System.Data.OracleClient需要Oracle客户端软件8.1.7或更高版本”
    详细讲解提高数据库查询效率的实用方法、外键关于性能
    解决ERRORORA12514:TNS:监听程序当前无法识别连接描述符中请求的服务
    session丢失问题
    Jquery AJAX WebService处理方式 demo
    DIV模拟弹出窗口(支持拖动)
  • 原文地址:https://www.cnblogs.com/asuldb/p/10725098.html
Copyright © 2011-2022 走看看