codeforces 917D Stranger Trees
正解:矩阵树定理+拉格朗日插值。
一下午就搞了这一道题,看鬼畜英文题解看了好久。。
首先这题出题人给了两种做法,感觉容斥+$prufer$序列+$dp$的做法细节有点多所以没看,然而这个做法似乎更难想。。
我们先构造一个函数$f(x)$,表示用一个完全图和$x-1$棵原树的边,构成的生成树的方案数。
也就是说,原树的每条边复制成$x$条,不在原树的边都变成一条边,求这个图的生成树的方案数。
然后我们可以发现,这个方案数实际上就等于$\sum_{i=0}^{n-1}x^{i}*ans_{i}$,其中$ans_{i}$表示询问的恰好有$i$条边的答案。
稍微解释一下,我们选定了原树的$i$条边,那么原树这$i$条边每条边就有$x$种选择,其他边只有$1$种选择。
然后现在我们的目标就变成了求出这个函数所表示的多项式的系数。
那么我们可以算出$x$取$[1,n]$的答案,用拉格朗日插值求出多项式,计算答案可以用矩阵树定理。
复杂度为$O(n^{4}+n^{3})$,写完题解以后发现也不是很难。。
#include <bits/stdc++.h>
#define il inline
#define RG register
#define ll long long
#define rhl (1000000007)
#define N (105) using namespace std; int a[N][N],g[N][N],p[N],ans[N],fac[N],ifac[N],inv[N],n,len; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return q*x;
} il int qpow(RG int a,RG int b){
RG int ans=;
while (b){
if (b&) ans=1LL*ans*a%rhl;
if (b>>=) a=1LL*a*a%rhl;
}
return ans;
} il int gauss(){
RG int res=;
for (RG int i=,id,inv;i<n;++i){
for (id=i;id<n && !a[id][i];++id); if (id>=n) return ;
if (id!=i){
for (RG int j=;j<n;++j) swap(a[i][j],a[id][j]);
res=-res;
}
res=1LL*res*a[i][i]%rhl,inv=qpow(a[i][i],rhl-);
for (RG int j=i+,tmp;j<n;++j){
if (!a[j][i]) continue;
tmp=1LL*a[j][i]*inv%rhl;
for (RG int k=i;k<n;++k)
a[j][k]=(a[j][k]-1LL*a[i][k]*tmp)%rhl;
}
}
return (res+rhl)%rhl;
} int main(){
#ifndef ONLINE_JUDGE
freopen("stranger.in","r",stdin);
freopen("stranger.out","w",stdout);
#endif
n=gi(),fac[]=ifac[]=;
for (RG int i=;i<=n;++i){
inv[i]=i==?:1LL*(rhl-rhl/i)*inv[rhl%i]%rhl;
fac[i]=1LL*fac[i-]*i%rhl;
ifac[i]=1LL*ifac[i-]*inv[i]%rhl;
}
for (RG int i=,u,v;i<n;++i)
u=gi(),v=gi(),g[u][v]=g[v][u]=;
for (RG int k=;k<=n;++k){
for (RG int i=;i<=n;++i)
for (RG int j=;j<=n;++j) a[i][j]=;
for (RG int i=;i<n;++i)
for (RG int j=i+,tmp;j<=n;++j){
tmp=g[i][j] ? k : ;
a[i][j]-=tmp,a[j][i]-=tmp;
a[i][i]+=tmp,a[j][j]+=tmp;
}
p[len=]=1LL*gauss()*ifac[k-]%rhl*ifac[n-k]%rhl;
if ((n-k)&) p[]=rhl-p[];
for (RG int t=,tmp;t<=n;++t){
if (k==t) continue; tmp=rhl-t;
for (RG int i=++len;~i;--i)
p[i]=(1LL*tmp*p[i]+(i?p[i-]:))%rhl;
}
for (RG int i=;i<=len;++i){
ans[i]+=p[i],p[i]=; if (ans[i]>=rhl) ans[i]-=rhl;
}
}
for (RG int i=;i<n;++i) printf("%d ",ans[i]); return ;
}
codeforces 917D Stranger Trees的更多相关文章
- Codeforces 917D - Stranger Trees(矩阵树定理/推式子+组合意义)
Codeforces 题目传送门 & 洛谷题目传送门 刚好看到 wjz 在做这题,心想这题之前好像省选前做过,当时觉得是道挺不错的题,为啥没写题解呢?于是就过来补了,由此可见我真是个大鸽子(( ...
- 题解-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$ 题解:我们先考虑容斥,求出 ...
- Solution -「CF 917D」Stranger Trees
\(\mathcal{Description}\) Link. 给定一棵包含 \(n\) 个点的有标号树,求与这棵树重合恰好 \(0,1,\cdots,n-1\) 条边的树的个数,对 \(10 ...
- Codeforces 677C. Coloring Trees dp
C. Coloring Trees time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...
- codeforces 711C Coloring Trees(DP)
题目链接:http://codeforces.com/problemset/problem/711/C O(n^4)的复杂度,以为会超时的 思路:dp[i][j][k]表示第i棵数用颜色k涂完后bea ...
- 【动态规划】Codeforces 711C Coloring Trees
题目链接: http://codeforces.com/problemset/problem/711/C 题目大意: 给N棵树,M种颜色,已经有颜色的不能涂色,没颜色为0,可以涂色,每棵树I涂成颜色J ...
- CF917D. Stranger Trees & TopCoder13369. TreeDistance(变元矩阵树定理+高斯消元)
题目链接 CF917D:https://codeforces.com/problemset/problem/917/D TopCoder13369:https://community.topcoder ...
随机推荐
- jQuery事件篇---过滤选择器 & 表单选择器
内容提纲: 过滤选择器 1.基本过滤器 2.内容过滤器 3.可见性过滤器 4.子元素过滤器 5.其他方法 表单选择器 6.常规选择器 7.表单选择器 8.表单过滤器 发文不易,转载请注明出处! 过滤选 ...
- 配置/etc/profile错误导致很多系统命令无法使用
在配置hadoop的环境变量的过程中,由于字符输入错误导致/etc/profile文件出错,并导致系统的基本命令不能使用,如:vi,ls等. 这种情况,首先修改/etc/profile的错误文件内容, ...
- 撩课-Python-每天5道面试题-第9天
一. Python程序中, 文件的处理步骤是什么? 打开 open("文件","模式") 读写 2.1 读 f.read(字节数) 字节数默认是文件内容长度 下 ...
- python学习之老男孩python全栈第九期_day027知识点总结——反射、类的内置方法
一. 反射 ''' # isinstance class A:pass class B(A):pass a = A() print(isinstance(a,A)) # 判断对象和类的关系 print ...
- Linux VPS主机利用Crontab实现定时重启任务
第一.安装Crontab可执行环境 一般的VPS/服务器是支持的,但是有些可能没有支持就需要我们来给予安装. A - centos系统 #安装Crontab yum install vixie-cro ...
- php备注
一.关于OOP 1.PHP目前不支持方法重载
- [算法练习]Reverse Integer
题目说明: Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return –321 ...
- Socket for android 简单实例
最近在实现socket通信,所以写个demo来简单实现下.我用了一种是原始的socket实现,另一种是MINA框架来实现的. 下载demo:http://download.csdn.net/detai ...
- Selenium+java项目测试问题整理
一.页面跳转到另一链接 问题描述:打开页面链接为A.com,但是页面元素需跳转到链接B.com.这时B页面将无法识别该元素,导致拨错 解决方案:重新自定义驱动,打开新链接 (PS:比较笨的解决方法,但 ...
- 5 TensorFlow实战Google深度学习框架一书中的错误两处(交叉熵定义有误)
第一处: 书中62页定义的交叉熵函数定义有误,虽然这个所谓交叉熵的数值能够减少,但是是不能提升预测性能的,因为定义就错了. 我已经将预测过程可视化,直接将交叉熵改为我的,或者用原书的,就可以看到预测结 ...