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. c# dllimport 调用函数,参数乱码

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalA ...

  2. struts2_项目运行报404

    1.缺少jar包,commons-lang3-3.2.jar 参考网址:https://blog.csdn.net/u013457382/article/details/50972401 2.stru ...

  3. SSM+Netty项目结合思路

    最近正忙于搬家,面试,整理团队开发计划等工作,所以没有什么时间登陆个人公众号,今天上线看到有粉丝想了解下Netty结合通用SSM框架的案例,由于公众号时间限制,我不能和此粉丝单独沟通,再此写一篇手记分 ...

  4. python基础学习(二)注释和算术运算符

    注释 1. 注释的作用 注释就是对某些代码进行标注说明,以增强代码的可读性.我们在写程序的时候,编写的某一部分代码的意图不太明显,这时候就需要对这一部分代码加以说明,来明确这一部分到的意图.一般的编程 ...

  5. JS中将变量转为字符串

    译者按: 语言的细枝末节了解一下就可以了,不需要太较真,不过如果一点也不知道的话,那就不太妙了. 原文: Converting a value to string in JavaScript 译者:  ...

  6. qW3xT.2,解决挖矿病毒。

    网站在运行期间感觉怪怪的,响应速度慢的不是一丁半点,带宽5M,不该是这样的呀 于是登录Xshell top命令 查看cpu情况如下 PID为3435的进程占用CPU过大,难道被病毒入侵了吗? 查看该进 ...

  7. JS使用cookie实现只出现一次的广告代码效果

    我们上网经常会遇到第一次需要登录而之后不用再登录的网站的情况,其实是运用了Cookie 存储 web 页面的用户信息,Cookie 以名/值对形式存储,当浏览器从服务器上请求 web 页面时, 属于该 ...

  8. es6 语法 (let 和const)

    一.let 和const 1.let 只在自己声明的块作用域中有效: function test(){ let a = 'a'; var b = 'b'; for(let i =1;i<3;i+ ...

  9. nginx 转将http跳转到https

    #websoceket 使用map map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream abc. ...

  10. layui 弹出框改变按钮颜色样式 自定义皮肤

    1.在layer下新建文件夹和css 文件: 2.123.css body .layui-ext-yourskin .layui-layer-btn0{ border-color: #55ff83; ...