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\) 条边相同,对 ...
随机推荐
- Codeforces Round #309 (Div. 2)
A. Kyoya and Photobooks Kyoya Ootori is selling photobooks of the Ouran High School Host Club. He ha ...
- vim 中:wq和:wq的不同之处
- js 实现二级联动
onchange 事件 <body> <select id="province" onchange="func1()"> <opt ...
- POJ 2942Knights of the Round Table(tarjan求点双+二分图染色)
Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 13954 Accepted: 4673 Description Bein ...
- Ios12怎么投屏到电脑 苹果手机投屏电脑的方法
苹果手机是一款外观精致时尚的手机,吸引这许多用户争先恐后的购买,然后苹果手机的系统不同于我们传统使用的安卓系统,它采用的是苹果自主研发的IOS系统,有许多操作与安卓手机不同,那么苹果手机怎么用呢?下面 ...
- java调用matlab
object result[]; result = pClass1.job_3in1(2, c, ws2, 1275, a, 0); string adg[]; adg = result[1].toS ...
- Java 创建线程/停止线程
继承 Thread 类 class MyThread1 extends Thread{ @Override public void run(){ System.out.println("继承 ...
- android笔试题二
1.android系统架构: Linux内核——标准库——Framework层——应用层 Linux层包括:Android系统的核心服务,硬件驱动,进程管理,系统安全等等 (现在又加了一层变成了:Li ...
- Android RecycleView多种布局实现(工厂模式)
RecycleView是个很常用的控件,很多APP中都可以看到它的身影,同时它也是个很难用的控件,主要就难在多种布局的实现. 在<第一行代码—Android>这本书里边有个RecycleV ...
- hdu-2018题(母牛问题)
HDU-2018题/*有一头母牛,它每年年初生一头小母牛.每头小母牛从第四个年头开始,每年年初也生一头小母牛.请编程实现在第n年的时候,共有多少头母牛?Input输入数据由多个测试实例组成,每个测试实 ...