某考试 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条线段和第 ...
随机推荐
- Android开发——HandlerThread以及IntentService详解
.HandlerThread Android API提供了HandlerThread来创建线程.官网的解释是: //Handy class for starting a new thread that ...
- Redis实现之压缩列表
压缩列表 压缩列表(ziplist)是列表键和哈希键的底层实现之一,当一个列表键只包含少量列表项,并且每个列表项要嘛是整数值,要嘛是比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现. ...
- 【Python】函数参数类型及用法
一.函数的参数类型 def hs(a1,a2,a3,...): ****statements 其中a1,a2,a3是函数的参数,函数的参数类型可分为:必须参数.默认参数.可变参数(不定长参数).关键 ...
- 设计模式之第13章-职责链模式(Java实现)
设计模式之第13章-职责链模式(Java实现) “请假都那么麻烦,至于么.”“咋的了?”“这不快过年了么,所以我想早两天回去,准备一下,买买东西什么的,然后去给项目经理请假,但是他说快过年了,所以这个 ...
- MongoDB快速入门学习笔记7 MongoDB的用户管理操作
1.修改启动MongoDB时要求用户验证加参数 --auth 即可.现在我们把MongoDB服务删除,再重新添加服务 mongod --dbpath "D:\work\MongoDB\dat ...
- Python+Selenium中级篇之-Python读取配置文件内容
本文来介绍下Python中如何读取配置文件.任何一个项目,都涉及到了配置文件和管理和读写,Python支持很多配置文件的读写,这里我们就介绍一种配置文件格式的读取数据,叫ini文件.Python中有一 ...
- PostgreSQL 配置内存参数
对于任何数据库软件,内存配置项都是很重要的配置项.在 PostgreSQL 主要有以下几个内存配置参数. shared_buffers: integer 类型,设置数据库服务器将使用的共享内存缓冲区数 ...
- 关于eclipse连接mysql jar包
步骤如下: 右键工程--选择build path -- add Libraries. 弹出框选user library,点击next. 弹出框点击add libraries . 继续点击new ,输 ...
- SQL2008非域环境直接使用WINDOWS登录的镜像设置
1.检查主库是否为完全备份 2.将数据库备份出来还原到同步库上(完整备份和事务日志分两次备份到同一个备份文件中,然后拷贝到同步机上) 3.用证书太麻烦了,我们直接用两个windows认真的账户 不分主 ...
- CH Round #59 - OrzCC杯NOIP模拟赛day1
第一题:队爷的新书 题意简述:给定n个闭区间,求出一个数p使它与包含它的区间数的积最大,输出这个积. 分析:使用一个差分数组g,每个区间[l,r],l位置加1,r+1的位置减1,从前往后统计,得到对于 ...