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

题意

求一个带权无向图所有生成树边权和的 \(k\) 次方的和。

思路

首先有一个结论:\(a^i\) 的 EGF 卷 \(b^i\) 的 EGF 等于 \((a+b)^i\) 的 EGF。即:

\[F(a)=\sum_{i=0}\frac{a^ix^i}{i!}\\
F(a+b)=F(a)*F(b)
\]

证明如下:

\[(a+b)^k=\sum_{i=0}^k{k\choose i}a^ib^{k-i}=\sum_{i=0}^k\frac{k!}{i!(k-i)!} a^ib^{k-i}\\
\Rightarrow \sum_{i=0}^k\frac{a^i}{i!}\frac{b^{k-i}}{(k-i)!}k!=(a+b)^k \\
\Rightarrow \sum_{i=0}^k\frac{a^i}{i!}\frac{b^{k-i}}{(k-i)!}=\frac{(a+b)^k}{k!}\\
\]

然后又有一个结论:度数矩阵减去邻接矩阵的余子式的行列式的值是图所有生成树边权积的和。其中,度数矩阵表示与其相连的边权的和,邻接矩阵为边权。这是矩阵树定理。

于是,我们将边权化为生成函数,然后利用矩阵树定理算出来答案的生成函数即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cmath>
using namespace std;
inline int read(){
int w=0,x=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=x*10+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=35,mod=998244353;
int n,k,mul[maxn],inv[maxn];
inline int fpow(int a,int b){int ans=1;for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) ans=1ll*ans*a%mod;return ans;}
struct poly{
int a[maxn];
poly():a(){}
poly(int x):a(){for(int i=0,d=1;i<=k;i++,d=1ll*d*x%mod) a[i]=1ll*star::inv[i]*d%mod;}
int& operator [](const int &x){return a[x];}
const int &operator [](const int &x) const {return a[x];}
friend poly operator + (const poly& a,const poly& b) {
poly ans;
for(int i=0;i<=k;i++) ans[i]=(a[i]+b[i])%mod;
return ans;
}
friend poly operator - (const poly& a,const poly& b) {
poly ans;
for(int i=0;i<=k;i++) ans[i]=(a[i]-b[i]+mod)%mod;
return ans;
}
friend poly operator * (const poly& a,const poly& b) {
poly ans;
for(int i=0;i<=k;i++) for(int j=0;j<=i;j++) ans[i]=(ans[i]+1ll*a[j]*b[i-j])%mod;
return ans;
}
inline poly operator - () const {
poly ans;
for(int i=0;i<=k;i++) ans[i]=(mod-a[i])%mod;
return ans;
}
inline poly inv() const {
poly ans,res;
ans[0]=fpow(a[0],mod-2);
for(int i=1;i<=k;i++) res[i]=1ll*a[i]*ans[0]%mod;
for(int i=1;i<=k;i++) for(int j=1;j<=i;j++) ans[i]=(ans[i]+1ll*(mod-res[j])*ans[i-j])%mod;
return ans;
}
}a[maxn][maxn],ans;
inline void work(){
n=read()-1,k=read();
mul[0]=inv[0]=1;
for(int i=1;i<=k;i++) mul[i]=1ll*mul[i-1]*i%mod;
inv[k]=fpow(mul[k],mod-2);for(int i=k-1;i>0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) if(i!=j) a[i][j]=-poly(read()),a[i][i]=a[i][i]-a[i][j];else read();
ans[0]=1;
for(int i=1;i<=n;i++){
poly x=a[i][i].inv();
ans=ans*a[i][i];
for(int j=i;j<=n;j++) a[i][j]=a[i][j]*x;
for(int j=1;j<=n;j++) if(j!=i){
poly res=a[j][i];
for(int k=i;k<=n;k++) a[j][k]=a[j][k]-a[i][k]*res;
}
}
printf("%lld\n",1ll*ans[k]*mul[k]%mod);
}
}
signed main(){
star::work();
return 0;
}

P5296 [北京省选集训2019]生成树计数的更多相关文章

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

    Luogu P5296 [北京省选集训2019]生成树计数 题目链接 题目大意:给定每条边的边权.一颗生成树的权值为边权和的\(k\)次方.求出所有生成树的权值和. 我们列出答案的式子: 设\(E\) ...

  2. 洛谷 P4002 - [清华集训2017]生成树计数(多项式)

    题面传送门 神题. 考虑将所有连通块缩成一个点,那么所有连好边的生成树在缩点之后一定是一个 \(n\) 个点的生成树.我们记 \(d_i\) 为第 \(i\) 个连通块缩完点之后的度数 \(-1\), ...

  3. Loj 2320.「清华集训 2017」生成树计数

    Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...

  4. 2019暑期金华集训 Day1 组合计数

    自闭集训 Day1 组合计数 T1 \(n\le 10\):直接暴力枚举. \(n\le 32\):meet in the middle,如果左边选了\(x\),右边选了\(y\)(且\(x+y\le ...

  5. 生成树计数 Matrix-Tree 定理 学习笔记

    一直都知道要用Matrix-Tree定理来解决生成树计数问题,但是拖到今天才来学.博主数学不好也只能跟着各位大佬博客学一下它的应用以及会做题,证明实在是不会. 推荐博客: https://www.cn ...

  6. 【BZOJ1002】【FJOI2007】轮状病毒(生成树计数)

    1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1766  Solved: 946[Submit][Status ...

  7. SPOJ 104 HIGH - Highways 生成树计数

    题目链接:https://vjudge.net/problem/SPOJ-HIGH 解法: 生成树计数 1.构造 基尔霍夫矩阵(又叫拉普拉斯矩阵) n阶矩阵 若u.v之间有边相连 C[u][v]=C[ ...

  8. 「UVA10766」Organising the Organisation(生成树计数)

    BUPT 2017 Summer Training (for 16) #6C 题意 n个点,完全图减去m条边,求生成树个数. 题解 注意可能会给重边. 然后就是生成树计数了. 代码 #include ...

  9. SPOJ.104.Highways([模板]Matrix Tree定理 生成树计数)

    题目链接 \(Description\) 一个国家有1~n座城市,其中一些城市之间可以修建高速公路(无自环和重边). 求有多少种方案,选择修建一些高速公路,组成一个交通网络,使得任意两座城市之间恰好只 ...

随机推荐

  1. python+selenium基础篇,句柄操作(多个页面切换)

    1.我们打开网页有时候会开出多个页面,导致我们常常定位不到我们需要的元素,这种情况可能就是句柄的因素,如下图所示: 2.句柄切换代码如下: from selenium import webdriver ...

  2. ipconfig提示不是内部或外部命令

    昨天因为公司断网,重新连上之后ip地址变了,于是就想看看现在的ip是什么 输入ipconfig,回车 提示不是外部和内部命令,是因为系统在本路径下未找到ipconfig.exe系统,所以无法识别ipc ...

  3. Go语言实现的23种设计模式之结构型模式

    摘要:本文主要聚焦在结构型模式(Structural Pattern)上,其主要思想是将多个对象组装成较大的结构,并同时保持结构的灵活和高效,从程序的结构上解决模块之间的耦合问题. 本文分享自华为云社 ...

  4. 深入理解Spring事务的那点事

    Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...

  5. codeforeces 845B

    题解 codefores 845B 原题 Luba has a ticket consisting of 6 digits. In one move she can choose digit in a ...

  6. MEMORY_TARGET不够时解决办法

    一.报错原因:设置的memory_max_target超过了系统中设置的share memory(/dev/shm)而已. 二.解决办法:增加tmpfs的大小 三.调整tmpfs的大小(两种方法) 1 ...

  7. MySQL 架构|给你一个“上帝视角”

    "我平时的工作就是 CRUD (增删改查)呀!我怎么提升自己的技术?"."平时开发我都是用开源的 MyBatis.Hibernate,连原生的 sql 我都没写过几行&q ...

  8. HTTP Cookies知识-查看、发送、获取、返回

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 HTTP Cookies是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求 ...

  9. 4、oracle表操作

    4.1.dml操作: 1.查看当前用户下所有的表: select * from user_tables; 2.查看某表的大小: select sum(bytes)/(1024*1024) as &qu ...

  10. 混沌工程之ChaosToolkit使用之一删除K8s POD

    今天我们来玩一下混沌工程的开源工具chaostoolkit . 它的目标是提供一个免费,开放,社区驱动的工具集以及api. 官方源码链接:https://github.com/chaostoolkit ...