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\),则我们有一下变换:

\[\begin{align}
\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的更多相关文章

  1. CF917D. Stranger Trees & TopCoder13369. TreeDistance(变元矩阵树定理+高斯消元)

    题目链接 CF917D:https://codeforces.com/problemset/problem/917/D TopCoder13369:https://community.topcoder ...

  2. CF917D Stranger Trees【矩阵树定理,高斯消元】

    题目链接:洛谷 题目大意:给定一个$n$个节点的树$T$,令$ans_k=\sum_{T'}[|T\cap T'|=k]$,即有$k$条边重合.输出$ans_0,ans_1,\ldots,ans_{n ...

  3. [CF917D]Stranger Trees[矩阵树定理+解线性方程组]

    题意 给你 \(n\) 个点的无向完全图,指定一棵树 \(S\),问有多少棵生成树和这棵树的公共边数量为 \(k\in[0,n-1]\) \(n\leq 100\) 分析 考虑矩阵树定理,把对应的树边 ...

  4. 【CF917D】Stranger Trees 树形DP+Prufer序列

    [CF917D]Stranger Trees 题意:给你一棵n个点的树,对于k=1...n,问你有多少有标号的n个点的树,与给出的树有恰好k条边相同? $n\le 100$ 题解:我们先考虑容斥,求出 ...

  5. 【CF917D】Stranger Trees

    题目 看题解的时候才突然发现\(zky\)讲过这道题啊,我现在怕不是一个老年人了 众所周知矩阵树求得是这个 \[\sum_{T}\prod_{e\in T}w_e\] 而我们现在的这个问题有些鬼畜了, ...

  6. 题解 CF917D 【Stranger Trees】

    生成树计数问题用矩阵树定理来考虑. 矩阵树定理求得的为\(\sum\limits_T\prod\limits_{e\in T}v_e\),也就是所有生成树的边权积的和. 这题边是不带权的,应用矩阵树定 ...

  7. codeforces 917D Stranger Trees

    题目链接 正解:矩阵树定理+拉格朗日插值. 一下午就搞了这一道题,看鬼畜英文题解看了好久.. 首先这题出题人给了两种做法,感觉容斥+$prufer$序列+$dp$的做法细节有点多所以没看,然而这个做法 ...

  8. Codeforces917D. Stranger Trees

    $n \leq 100$的完全图,对每个$0 \leq K \leq n-1$问生成树中与给定的一棵树有$K$条公共边的有多少个,答案$mod \ \ 1e9+7$. 对这种“在整体中求具有某些特性的 ...

  9. 题解-Codeforces917D Stranger Trees

    Problem \(\mathrm{Codeforces~917D}\) 题意概要:一棵 \(n\) 个节点的无向树.问在 \(n\) 个点的完全图中,有多少生成树与原树恰有 \(k\) 条边相同,对 ...

随机推荐

  1. Android Studio 使用Menu

    首先在res目录下创建一个文件夹名字随意 在对创建的文件夹下在创建一个菜单 名字随意 参看布局 可以看到你的菜单 可以选择添加是么样的菜单 接着要到主活动中重写 onCreateOptionsMenu ...

  2. C# 插入条码到Excel指定单元格

    .NET中Barcode Library的应用二 介绍 在上一篇中我已经简单介绍了这个函数库(条形码应用之一------------函数库的简介).在这一篇中我将使用这个库提供更多的操作,希望对大家有 ...

  3. Java基础IO流(五)RandomAccessFile

    RandomAccessFile java提供的对文件内容的访问,既可以读文件也可以写文件.RandomAccessFile支持随机访问文件,可以访问文件的任意位置 (1)java文件模型:    在 ...

  4. thinkphp模板中,checkbox回显问题

    thinkphp 模板里面可以这样写包含操作 //in 标签 <in name="变量名" value="值1,值2,...">要输出的内容< ...

  5. 2018-12-16 VS Code英汉词典进化效果演示: 翻译文件所有命名

    续VS Code英汉词典插件v0.0.7-尝试词性搭配, 下一个功能打算实现文件的批量命名翻译: 批量代码汉化工具 · Issue #86 · program-in-chinese/overview ...

  6. 2018-06-21 中文代码示例视频演示Python入门教程第五章 数据结构

    知乎原链 续前作: 中文代码示例视频演示Python入门教程第四章 控制流 对应在线文档: 5. Data Structures 这一章起初还是采取了尽量与原例程相近的汉化方式, 但有些语义较偏(如T ...

  7. TS学习随笔(二)->类型推论,联合类型

    这篇内容指南:        -----类型推论  -----联合类型 类型推论 第一篇中我们看了TS的基本使用和基本数据类型的使用,知道了变量在使用的时候都得加一个类型,那我们可不可以不加呢,这个嘛 ...

  8. mac 苹果多版本jdk自由切换

    场景 手头上的工具有时候依赖低版本jdk,有时候需要高版本jdk, 如何在不同版本jdk之间来回自由的切换? 安装 首选需要去官网下载dmg安装包,地址:https://www.oracle.com/ ...

  9. Bootstrap table 分页 In asp.net MVC

    中文翻译文档: http://blog.csdn.net/rickiyeat/article/details/56483577 版本说明: Jquery v2.1.1 Bootstrap V3.3.7 ...

  10. Symantec Backup Exec 2010 安装报 bad ELF interpreter: No such file or directory

    在64位的Red Hat Enterprise Linux Server release 6.6上安装Symantec Backup Exec 2010时, 遇到下面错误: # ./installra ...