Codeforces917D. Stranger Trees
$n \leq 100$的完全图,对每个$0 \leq K \leq n-1$问生成树中与给定的一棵树有$K$条公共边的有多少个,答案$mod \ \ 1e9+7$。
对这种“在整体中求具有某些特性的部分”,可以通过把“特性”强行复制加入“整体”来考察新的整体与部分的关系。
说人话,在这里是要求完全图中与给定树有若干同样边的生成树,那尝试把这棵树复制一份进完全图再看生成树。可以发现,这样之后,新的完全图的生成树个数就是
$\sum_{i=0}^{n-1}2^i*[number \ \ of \ \ trees \ \ which \ \ have \ \ i \ \ common \ \ edges \ \ with \ \ the \ \ original \ \ tree]$
因为有$i$条公共边的话他在这张图里面这些公共边都有两种选择。类似得可以发现原完全图的生成树个数实际上就是所有要求的系数之和,原完全图相当于复制0次。依次类推,设$F(x)$为把树边复制$x-1$次得到完全图的生成树个数,那么
$F(x)=\sum_{i=0}^{n-1}x^i*[number \ \ of \ \ trees \ \ which \ \ have \ \ i \ \ common \ \ edges \ \ with \ \ the \ \ original \ \ tree]$
现在要求这些系数,但我们知道了n个自变量$x$和他们对应的$F(x)$(用无向图生成树计数--矩阵树定理),可以用多项式插值求出系数。我只会高斯消元求插值,因此复杂度$n^3+n^4$。
//#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
//#include<map>
#include<math.h>
//#include<time.h>
//#include<complex>
#include<algorithm>
using namespace std; int n,m;
#define maxn 111
const int mod=1e9+;
int ji[maxn][maxn],duo[maxn][maxn]; int powmod(int a,int b)
{
int ans=;
while (b)
{
if (b&) ans=1ll*ans*a%mod;
a=1ll*a*a%mod; b>>=;
}
return ans;
} int hh(int n)
{
int ans=;
for (int i=;i<=n;i++)
{
if (ji[i][i]==) for (int j=i+;j<=n;j++) if (ji[j][i])
{
ans=ans==?mod-:;
for (int k=i;k<=n;k++) {int t=ji[i][k]; ji[i][k]=ji[j][k]; ji[j][k]=t;}
break;
}
int pp=powmod(ji[i][i],mod-);
for (int j=i+;j<=n;j++)
{
int now=1ll*ji[j][i]*pp%mod;
for (int k=i;k<=n;k++) ji[j][k]-=1ll*ji[i][k]*now%mod,ji[j][k]+=ji[j][k]<?mod:;
}
}
for (int i=;i<=n;i++) ans=1ll*ans*ji[i][i]%mod;
return ans;
} void gauss(int n)
{
for (int i=;i<=n;i++)
{
if (duo[i][i]==) for (int j=i+;j<=n;j++) if (duo[j][i])
{
for (int k=i;k<=n+;k++) {int t=duo[i][k]; duo[i][k]=duo[j][k]; duo[j][k]=t;}
break;
}
int pp=powmod(duo[i][i],mod-);
for (int j=i+;j<=n;j++)
{
int now=1ll*duo[j][i]*pp%mod;
for (int k=i;k<=n+;k++) duo[j][k]-=1ll*duo[i][k]*now%mod,duo[j][k]+=duo[j][k]<?mod:;
}
}
for (int i=n;i;i--)
{
for (int j=n;j>i;j--) duo[i][n+]-=1ll*duo[i][j]*duo[j][n+]%mod,duo[i][n+]+=duo[i][n+]<?mod:;
duo[i][n+]=1ll*duo[i][n+]*powmod(duo[i][i],mod-)%mod;
}
} int mp[maxn][maxn],du[maxn],base[maxn][maxn];
int main()
{
scanf("%d",&n);
for (int i=,x,y;i<n;i++)
{
scanf("%d%d",&x,&y);
mp[x][y]++; mp[y][x]++; du[x]++; du[y]++;
}
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
{
if (i==j) base[i][j]=n-;
else base[i][j]=mod-;
}
for (int i=;i<n;i++)
{
memcpy(ji,base,sizeof(ji));
for (int j=;j<=n;j++) ji[j][j]+=du[j]*i;
for (int j=;j<=n;j++)
for (int k=;k<=n;k++)
if (j!=k && mp[j][k]) ji[j][k]-=i;
duo[i+][n+]=hh(n-);
for (int j=,tmp=;j<=n;j++,tmp=1ll*tmp*(i+)%mod) duo[i+][j]=tmp;
}
gauss(n);
for (int i=;i<=n;i++) printf("%d ",duo[i][n+]);
return ;
}
Codeforces917D. Stranger Trees的更多相关文章
- 题解-Codeforces917D Stranger Trees
Problem \(\mathrm{Codeforces~917D}\) 题意概要:一棵 \(n\) 个节点的无向树.问在 \(n\) 个点的完全图中,有多少生成树与原树恰有 \(k\) 条边相同,对 ...
- CF917D Stranger Trees
CF917D Stranger Trees 题目描述 给定一个树,对于每个\(k=0,1\cdots n-1\),问有多少个生成树与给定树有\(k\)条边重合. 矩阵树定理+高斯消元 我们答案为\(f ...
- 【CF917D】Stranger Trees 树形DP+Prufer序列
[CF917D]Stranger Trees 题意:给你一棵n个点的树,对于k=1...n,问你有多少有标号的n个点的树,与给出的树有恰好k条边相同? $n\le 100$ 题解:我们先考虑容斥,求出 ...
- codeforces 917D Stranger Trees
题目链接 正解:矩阵树定理+拉格朗日插值. 一下午就搞了这一道题,看鬼畜英文题解看了好久.. 首先这题出题人给了两种做法,感觉容斥+$prufer$序列+$dp$的做法细节有点多所以没看,然而这个做法 ...
- [CF917D]Stranger Trees[矩阵树定理+解线性方程组]
题意 给你 \(n\) 个点的无向完全图,指定一棵树 \(S\),问有多少棵生成树和这棵树的公共边数量为 \(k\in[0,n-1]\) \(n\leq 100\) 分析 考虑矩阵树定理,把对应的树边 ...
- 【CF917D】Stranger Trees
题目 看题解的时候才突然发现\(zky\)讲过这道题啊,我现在怕不是一个老年人了 众所周知矩阵树求得是这个 \[\sum_{T}\prod_{e\in T}w_e\] 而我们现在的这个问题有些鬼畜了, ...
- 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】
生成树计数问题用矩阵树定理来考虑. 矩阵树定理求得的为\(\sum\limits_T\prod\limits_{e\in T}v_e\),也就是所有生成树的边权积的和. 这题边是不带权的,应用矩阵树定 ...
随机推荐
- 迭代器模式及php实现
迭代器模式: 迭代器模式是遍历集合的成熟模式,迭代器模式的关键是将遍历集合的任务交给一个叫做迭代器的对象,它的工作时遍历并选择序列中的对象,而客户端程序员不必知道或关心该集合序列底层的结构. 角色: ...
- windows下常用的一些shell命令
看的视频上都是linux系统的shell命令,和windows区别很多.所以整理了windows常用的一些shell命令. 注意:并不是每个都试验过,使用时还需自己验证下. 学system和os,su ...
- [ AHOI 2013 ] 作业 & [ BZOJ 3809 ] Gty的二逼妹子序列
\(\\\) Description 给出一个长为 \(n\) 的数列 \(A\) 和 \(k\),多次询问: 对于一个区间 \([L_i,R_i]\),问区间内有多少个数在 \([a_i,b_i]\ ...
- VUE学习——vue的内部指令学习(趁自己没忘,学习记录一下)
1.v-if&v-else&v-show v-if用来判断是否加载html的DOM,v-if和v-else一般是一起用的. v-show相当于display,DOM已经加载出来了,这个 ...
- Eigen3的安装
- Android如何用阿里云的API进行身份证识别
准备工作:在libs下添加 alicloud-Android-apigateway-sdk-1.0.1.jar,commons-codec-1.10-1.jar 在build.gradle添加 co ...
- VCS filelist 文件格式
VCS在运行仿真一般都会加仿真参数 –f filelist,filelist 是包含其他的仿真参数和整个工程的文件列表.具体格式如下: //file list format, just for exa ...
- 第16周翻译:SQL Server中的事务日志管理,级别3:事务日志、备份和恢复
源自: http://www.sqlservercentral.com/articles/Stairway+Series/73779/ 作者: Tony Davis, 2011/09/07 翻译:刘琼 ...
- 设置QtreeWidget水平滚动条
转载请注明出处:http://www.cnblogs.com/dachen408/p/7552603.html //设置treewidget水平滚动条 ui.treeWidget->header ...
- js单线程和js异步操作的几种方法
一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事. JavaScript的单线程,与它的用途有关.作为浏览器脚本语言,JavaS ...