CF917D Stranger Trees
CF917D Stranger Trees
给定一个树,对于每个\(k=0,1\cdots n-1\),问有多少个生成树与给定树有\(k\)条边重合。
矩阵树定理+高斯消元
我们答案为\(f_k\)。假设我们呢将原树上的边权设为\(x\),其他的边权设为\(1\),那么我们做一次矩阵树定理求出来的东西就是\(\displaystyle \sum_{i=0}^{n-1}f_i x^i\)。于是我们找\(n\)个不同的\(x\),然后高斯消元就行了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define N 105
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
int n;
ll a[N][N],d[N];
ll w[N][N];
ll c[N][N],ans[N];
ll ksm(ll t,ll x) {
ll ans=1;
for(;x;x>>=1,t=t*t%mod)
if(x&1) ans=ans*t%mod;
return ans;
}
void Gauss(ll a[N][N],int n) {
for(int i=1;i<=n;i++) {
for(int j=i+1;j<=n;j++) {
ll t=ksm(a[i][i],mod-2)*a[j][i]%mod;
for(int k=i;k<=n+1;k++) a[j][k]=(a[j][k]-t*a[i][k]%mod+mod)%mod;
}
}
}
int main() {
n=Get();
for(int i=1;i<n;i++) {
int x=Get(),y=Get();
a[x][y]=a[y][x]=1;
d[x]++,d[y]++;
}
for(int v=1;v<=n;v++) {
memset(w,0,sizeof(w));
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
if(i==j) w[i][j]=d[i]*v+n-1-d[i];
else if(a[i][j]) w[i][j]=mod-v;
else w[i][j]=mod-1;
}
}
Gauss(w,n-1);
c[v][n+1]=1;
for(int i=1;i<n;i++) c[v][n+1]=c[v][n+1]*w[i][i]%mod;
ll now=1;
for(int i=1;i<=n;i++,now=now*v%mod) c[v][i]=now;
}
Gauss(c,n);
for(int i=n;i>=1;i--) {
for(int j=i+1;j<=n;j++) {
c[i][n+1]=(c[i][n+1]-ans[j]*c[i][j]%mod+mod)%mod;
}
ans[i]=ksm(c[i][i],mod-2)*c[i][n+1]%mod;
}
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
return 0;
}
容斥原理+prufer序列
我们的原理就是选定\(k\)个边与原树重合,这样我们将原树分成了\(n-k\)个联通块。我们求出此时的生成树方案树,表示至少\(k\)条边重合的方案树,然后容斥就好了。
具体求法如下:
给定一颗森林,每个联通块的大小是\(a_i\),那么这个森林的生成树方案树我们也可以用\(prufer\)序列来求。将每个连通块视作点,设第\(i\)个块出现的次数为\(t_i\),则一个序列的答案为\(\prod a_i^{t_i}\)。
我们设所有\(prufer\)序列为\(P\),则我们有一下变换:
\displaystyle
ans&=(\prod_{i=1}^k a_i)\sum_{p\in P}\prod_{i=1}^{k-2}a_{p_i}\\
&=(\prod_{i=1}^k a_i)\prod_{i=1}^{k-2}\sum_{j=1}^ka_j\\
&=(\prod_{i=1}^k a_i)\prod_{i=1}^{k-2}n^{k-2}\\
\end{align}
\]
\(\sum_{p\in P}\prod_{i=1}^{k-2}a_{p_i}=\prod_{i=1}^{k-2}\sum_{j=1}^ka_j\)就是一个经典的和式变换。
得到上述的结论过后,我们就可以树形\(DP\)了。设\(f_{i,j,k}\)表示已\(i\)为根的子树中,分成了\(j\)个连通块,\(i\)所在的连通块的大小为\(k\)的生成树数量。
代码:
没写
CF917D Stranger Trees的更多相关文章
- CF917D. Stranger Trees & TopCoder13369. TreeDistance(变元矩阵树定理+高斯消元)
题目链接 CF917D:https://codeforces.com/problemset/problem/917/D TopCoder13369:https://community.topcoder ...
- CF917D Stranger Trees【矩阵树定理,高斯消元】
题目链接:洛谷 题目大意:给定一个$n$个节点的树$T$,令$ans_k=\sum_{T'}[|T\cap T'|=k]$,即有$k$条边重合.输出$ans_0,ans_1,\ldots,ans_{n ...
- [CF917D]Stranger Trees[矩阵树定理+解线性方程组]
题意 给你 \(n\) 个点的无向完全图,指定一棵树 \(S\),问有多少棵生成树和这棵树的公共边数量为 \(k\in[0,n-1]\) \(n\leq 100\) 分析 考虑矩阵树定理,把对应的树边 ...
- 【CF917D】Stranger Trees 树形DP+Prufer序列
[CF917D]Stranger Trees 题意:给你一棵n个点的树,对于k=1...n,问你有多少有标号的n个点的树,与给出的树有恰好k条边相同? $n\le 100$ 题解:我们先考虑容斥,求出 ...
- 【CF917D】Stranger Trees
题目 看题解的时候才突然发现\(zky\)讲过这道题啊,我现在怕不是一个老年人了 众所周知矩阵树求得是这个 \[\sum_{T}\prod_{e\in T}w_e\] 而我们现在的这个问题有些鬼畜了, ...
- 题解 CF917D 【Stranger Trees】
生成树计数问题用矩阵树定理来考虑. 矩阵树定理求得的为\(\sum\limits_T\prod\limits_{e\in T}v_e\),也就是所有生成树的边权积的和. 这题边是不带权的,应用矩阵树定 ...
- codeforces 917D Stranger Trees
题目链接 正解:矩阵树定理+拉格朗日插值. 一下午就搞了这一道题,看鬼畜英文题解看了好久.. 首先这题出题人给了两种做法,感觉容斥+$prufer$序列+$dp$的做法细节有点多所以没看,然而这个做法 ...
- Codeforces917D. Stranger Trees
$n \leq 100$的完全图,对每个$0 \leq K \leq n-1$问生成树中与给定的一棵树有$K$条公共边的有多少个,答案$mod \ \ 1e9+7$. 对这种“在整体中求具有某些特性的 ...
- 题解-Codeforces917D Stranger Trees
Problem \(\mathrm{Codeforces~917D}\) 题意概要:一棵 \(n\) 个节点的无向树.问在 \(n\) 个点的完全图中,有多少生成树与原树恰有 \(k\) 条边相同,对 ...
随机推荐
- UML 用例建模
用例建模 用例建模的主要功能是表达系统的功能性需求或行为.主要包含用例图和用例描述,其中用例图由参与者.用例.系统边界和箭头组成,用例描述以文本文档的形式详细的描述了用例图中的每个用例. ...
- [android] 代码注册广播接收者&利用广播调用服务的方法
利用广播调用服务里面的方法,间接的方式调用服务内部的方法,与现实中差不多,请媒体曝光 主界面里面 在界面创建的时候开启一下服务普通的startService()方法 发送一条广播出去 获取Intent ...
- C# 插入条码到Excel指定单元格
.NET中Barcode Library的应用二 介绍 在上一篇中我已经简单介绍了这个函数库(条形码应用之一------------函数库的简介).在这一篇中我将使用这个库提供更多的操作,希望对大家有 ...
- P、NP、NPC、NP-Hard问题到底是何方神圣?
最近在做一个求解有向图中回路的问题,老师说求解图中全部回路是一个NP难问题.突然想到P.NP.NPC.NP-hard的描述一致不是很清楚,所以又学习了一下. 在解释这四个概念之前,我们需要先知道两个问 ...
- SpringBoot中并发定时任务的实现、动态定时任务的实现(看这一篇就够了)
原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10659045.html,否则将追究法律责任!!! 一.在JAVA开发领域,目前可以通过以下 ...
- js操作css样式,null和undefined的区别?
1.js操作css的样式 div.style.width="100px"在div标签内我们添加了一个style属性,并设定了width值.这种写法会给标签带来大量的style属性, ...
- .Net Mvc 异步编程
关于在mvc/webapi 中 async/await 异步编程的探究和整理 你可以用双手玩转多个球 查看调试器windbg和sos.dll调试器扩展或挖掘W3SVC日志 设置minWorkerThr ...
- 小tips:JS数值之间的转换,JS中最大的Number是多少?,JS == 与 === 的区别
JS数值之间的转换 Number(), parseInt(),parseFloat() Number()函数的转换规则如下: 1.如果boolean值,true和false将分别被转换为1和02.如果 ...
- vuejs通过filterBy,orderBy实现搜索筛选,降序排序数据实例
直接贴代码了: 先上输入前的样子: <style> #example{margin:100px auto;width:600px;} .show{margin:10px;} #search ...
- redis redis常用命令及内存分析总结(附RedisClient工具简介
redis常用命令及内存分析总结(附RedisClient工具简介 by:授客 QQ:1033553122 redis-cli工具 查看帮助 连接redis数据库 常用命令 exists key se ...