某考试 T2 Tree
2 树
2.1 题目描述
给一棵n 个节点的树,节点分别编号为0 到n - 1。
你可以通过如下的操作来修改这棵树:首先先删去树上的一条边,此时树
会分裂为两个连通块,然后在两个连通块之间加上一条新的边使得它们变成一
棵新的树。
问有多少棵n 个节点的树可以通过对原树进行不超过k 次这样的操作来
得到,答案对109 + 7 取模。如果有一条边(u; v) 出现在了树A 中且不在树B
中,我们就认为树A 和树B 是不同的。
2.2 输入格式
第一行为两个整数n; k。
接下来一行用n - 1 个整数a1; a2; a3; :::; an-1 描述给定的树。其中ai 表
示节点i 和节点ai 之间有一条边,保证ai < i。
2.3 输出格式
输出一个整数表示答案对109 + 7 取模后的值。
2.4 输入样例一
3 1
0 0
2.5 输出样例一
3
2.6 输入样例二
6 4
0 1 1 3 3
2.7 输出样例二
1196
2.8 输入样例三
20 10
0 0 1 1 3 2 3 0 1 7 5 9 4 0 6 15 14 10 15
2.9 输出样例三
540101309
2.10 数据范围与约定
对于100% 的数据,n<=80,k<n。
当时考试的时候先做的T1和T3然后就没时间做这个题了,,,
但是可能当时我有时间也做不出来吧23333.
正解是矩阵树定理+高斯消元/拉格朗日插值法。
因为最多只能选k条不是原来树上的边,所以我们可以把树边看成1,把非树边看成x。
最后的答案就是矩阵树定理消出的多项式的x^k及之前的项的系数和。
这个当然可以暴力多项式乘法(因为多项式的项数不多但是有很多多项式要相乘,所以此时的NTT是没有暴力快的),
但是这样太慢了,大数据会挂。
我们还可以发现最后的多项式是一个n-1次多项式,所以我们可以带n对点来确定这个多项式。
这样的复杂度是 O(N^4) ,开开心心过本题。。。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=87;
const int ha=1000000007;
int n,k,a[maxn][maxn];
int fa,b[maxn][maxn];
int c[maxn][maxn],ans; inline int add(int x,int y){
x+=y;
return x>=ha?x-ha:x;
} inline int ksm(int x,int y){
int an=1;
for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
return an;
} inline int matrix_tree(int x){
int an=1;
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
if(a[i][j]) b[i][j]=b[j][i]=ha-1,b[i][i]++,b[j][j]++;
else b[i][j]=b[j][i]=ha-x,b[i][i]+=x,b[j][j]+=x;
} for(int i=1;i<n;i++){
int tmp=i;
for(;tmp<n;tmp++) if(b[tmp][i]) break;
if(tmp>i){
an=ha-an;
for(int k=i;k<n;k++) swap(b[i][k],b[tmp][k]);
} for(int j=i+1;j<n;j++)
while(b[j][i]){
an=ha-an;
int A=b[i][i]/b[j][i];
for(int k=i;k<n;k++){
b[i][k]=((ll)b[i][k]-b[j][k]*(ll)A)%ha;
if(b[i][k]<0) b[i][k]+=ha;
swap(b[i][k],b[j][k]);
}
} an=an*(ll)b[i][i]%ha;
} return an;
} inline void xy(){
n++;
for(int i=1;i<n;i++){
if(!c[i][i]){
for(int j=i+1;j<n;j++) if(c[j][i]){
for(int k=i;k<=n;k++) swap(c[j][k],c[i][k]);
break;
}
} for(int j=i+1;j<n;j++)
while(c[j][i]){
int A=c[i][i]/c[j][i];
for(int k=i;k<=n;k++){
c[i][k]=((ll)c[i][k]-c[j][k]*(ll)A)%ha;
if(c[i][k]<0) c[i][k]+=ha;
swap(c[i][k],c[j][k]);
}
}
} for(int i=n-1;i;i--){
for(int j=n-1;j>i;j--) c[i][n]=add(c[i][n],add(ha,-c[j][n]*(ll)c[i][j]%ha));
c[i][n]=c[i][n]*(ll)ksm(c[i][i],ha-2)%ha;
}
} int main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout); scanf("%d%d",&n,&k);
for(int i=2;i<=n;i++){
scanf("%d",&fa);
fa++,a[i][fa]++,a[fa][i]++;
} for(int i=1;i<=n;i++){
for(int j=1,u=1;j<=n;j++,u=u*(ll)i%ha) c[i][j]=u;
c[i][n+1]=matrix_tree(i);
} xy(); k++;
for(int i=1;i<=k;i++) ans=add(ans,c[i][n]); printf("%d\n",ans); return 0;
}
某考试 T2 Tree的更多相关文章
- 9.13 考试 T2 区间
删区间 题意: 给出一个长度为
- 2019.3.7考试T2 离线数论??
$ \color{#0066ff}{ 题目描述 }$ 一天,olinr 在 luogu.org 刷题,一点提交,等了一分钟之后,又蛙又替. olinr 发动了他的绝招,说:"为啥啊???&q ...
- 某考试T2 frog
题目背景 无 题目描述 数轴上有 n 只青蛙,分别编号为 1 到 n.青蛙 i 的初始位置的坐标为 xi. 它们准备进行如下形式的移动:每轮包括 m 次跳跃,第 i 次跳跃由青蛙 ai(1 < ...
- 某考试 T2 yja
2.1 Description 在平面上找 n 个点, 要求这 n 个点离原点的距离分别为 r1, r2, ..., rn. 最大化这 n 个点构成的凸包面积, 凸包上的点的顺序任意. 2.2 Inp ...
- 题解 2020.10.24 考试 T2 选数
题目传送门 题目大意 见题面. 思路 本来以为zcx.pxj变强了,后来发现是SPJ出问题了...考试的时候感觉有点人均啊...结果自己还是只想出来一半. 我们假设 \(f(x)=(\lfloor\f ...
- 某考试 T2 orzcyr
非常nice的一道行列式的题目. 考虑如果没有路径不相交这个限制的话,那么这个题就是一个行列式:设 a[i][j] 为从编号第i小的源点到编号第j小的汇点的路径条数,那么矩阵a[][]的行列式就是的答 ...
- 2019.2.26考试T2 矩阵快速幂加速DP
\(\color{#0066ff}{题解 }\) 可以发现, 数据范围中的n特别小,容易想到状压 可以想到类似于状压DP的思路,按列进行转移 那么应该有3维,\(f[i][j][k]\)代表到第i列, ...
- 2019.2.10考试T2, 多项式求exp+生成函数
\(\color{#0066ff}{ 题目描述 }\) 为了减小文件大小,这里不写一堆题目背景了. 请写一个程序,输入一个数字N,输出N个点的森林的数量.点有标号. 森林是一种无向图,要求图中不能存在 ...
- 某考试 T2 Seg
Seg [问题描述]数轴上有n条线段,第i条线段的左端点是a[i],右端点是b[i].Bob发现1~2n共2n个整数点,每个点都是某条线段的端点.这些线段有如下两类特点:1 x y,表示第x条线段和第 ...
随机推荐
- 3 View - Response对象
1. HttpResponse对象:返回数据 from django.http import HttpResponse 在django.http模块中定义了HttpResponse对象的API Htt ...
- 1026: [SCOI2009]windy数(数位dp)
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9016 Solved: 4085[Submit][Sta ...
- Redis实现之对象(一)
对象 前面我们介绍了Redis的主要数据结构,如:简单动态字符串SDS.双端链表.字典.压缩列表.整数集合等.Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象 ...
- “帮你APP”团队冲刺8
1.整个项目预期的任务量 (任务量 = 所有工作的预期时间)和 目前已经花的时间 (所有记录的 ‘已经花费的时间’),还剩余的时间(所有工作的 ‘剩余时间’) : 所有工作的预期时间:88h 目前已经 ...
- error LNK2001: unresolved external symbol __imp___time64
Q: vs2005 generate a static lib(libva.lib), used in vc++6.0, error LNK2001: unresolved external symb ...
- android基础知识杂记
Activity中获取视图组件对象:public View findViewById(@IdRes int id) 该方法以组件的资源ID为参数,返回一个视图对象View,需要强转成具体的视图类对象. ...
- sc.exe
sc.exe 编辑 本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! 服务管理程序:可用sc.exe远程创建 外文名 sc.exe 停止事件服务 sc stop eventl ...
- 63、加速android应用(转载)
本文转自 http://www.devtf.cn/?p=1097 原文链接 : Speed up your app原文作者 : UDI COHEN译文出自 : 开发技术前线 www.devtf.cn. ...
- 项目太多工作环境互相干扰?virtualenv 一招教你轻松解决。
写在之前 在上一篇文章 安装的 Python 版本太多互相干扰?以后再也不用担心这个问题了. 中我给大家介绍了一个 Python 版本的管理工具「pyenv」,可以很容易的安装不同的 Python 版 ...
- linux批量匹配移动文件的方法
需求 有需要移动的文件名清单 filename.txt filename.txt 内容如下: 15542842 1582457 1282427 1532158 4542457 1582453 6552 ...