[xsy2289]B
题意:给一棵树,一次操作定义为删掉一条树边再加一条边,并且满足加完边后这还是一棵树,问在进行不超过$k$次操作后能构造出多少种不同的树
首先...矩阵树定理在边有边权的时候同样适用,这时可以把它看成重边,此时直接按原方法求得的是所有生成树的边权乘积之和
所以我们可以把这棵树补成一个完全图,令补上去的边边权为$x$,那么答案就是求出来的多项式的$0\cdots k$次系数之和
直接带着多项式做当然不行,所以我们就用单位根作为$x$,求值后IDFT回去即可
我的代码在$k=n-1$时会错...?
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=998244353;
int mul(int a,int b){return a*(ll)b%mod;}
int ad(int a,int b){return(a+b)%mod;}
int de(int a,int b){return(a-b)%mod;}
int pow(int a,int b){
int s=1;
while(b){
if(b&1)s=mul(s,a);
a=mul(a,a);
b>>=1;
}
return s;
}
int rev[64],N,iN;
void pre(int n){
int i,k;
for(N=1,k=0;N<=n;N<<=1)k++;
for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
iN=pow(N,mod-2);
}
void ntt(int*a,int on){
int i,j,k,t,w,wn;
for(i=0;i<N;i++){
if(i<rev[i])swap(a[i],a[rev[i]]);
}
for(i=2;i<=N;i<<=1){
wn=pow(3,on==1?(mod-1)/i:mod-1-(mod-1)/i);
for(j=0;j<N;j+=i){
w=1;
for(k=0;k<i>>1;k++){
t=mul(w,a[i/2+j+k]);
a[i/2+j+k]=de(a[j+k],t);
a[j+k]=ad(a[j+k],t);
w=mul(w,wn);
}
}
}
if(on==-1){
for(i=0;i<N;i++)a[i]=mul(a[i],iN);
}
}
int d[64],tr[64][64],g[64][64],n;
int gauss(int n){
int i,j,k,t,c,s;
s=1;
for(i=1;i<=n;i++){
t=pow(g[i][i],mod-2);
for(j=i+1;j<=n;j++){
c=mul(t,g[j][i]);
for(k=i;k<=n;k++)g[j][k]=de(g[j][k],mul(c,g[i][k]));
}
s=mul(s,g[i][i]);
}
return s;
}
int solve(int x){
int i,j;
memset(g,0,sizeof(g));
for(i=1;i<=n;i++)g[i][i]=ad(d[i],mul(n-1-d[i],x));
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i!=j){
if(tr[i][j])
(g[i][j]-=1)%=mod;
else
(g[i][j]-=x)%=mod;
}
}
}
return gauss(n-1);
}
int po[64];
int main(){
int k,i,x,s;
scanf("%d%d",&n,&k);
if(k==n-1){
printf("%d",pow(n,n-2));
return 0;
}
for(i=2;i<=n;i++){
scanf("%d",&x);
x++;
tr[x][i]=tr[i][x]=1;
d[x]++;
d[i]++;
}
pre(n);
for(i=0;i<N;i++)po[i]=solve(pow(3,(mod-1)/N*i));
ntt(po,-1);
s=0;
for(i=0;i<=k;i++)s=ad(s,po[i]);
printf("%d",ad(s,mod));
}
[xsy2289]B的更多相关文章
随机推荐
- .NET Core Data Access
.NET Core was released a few months ago, and data access libraries for most databases, both relation ...
- charles https抓包
1. 配置 Charles 根证书 首先打开 Charles: Charles 启动界面 主界面 然后如下图操作: 之后会弹出钥匙串,如果不弹出,请自行打开钥匙串,如下图: 钥匙串 系统默认是不信 ...
- 【CSS】凹槽的写法
效果图: 实例代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...
- Django rest framework 权限操作(源码分析)
知识回顾http://www.cnblogs.com/ctztake/p/8419059.html 这一篇是基于上一篇写的,上一篇谢了认证的具体流程,看懂了上一篇这一篇才能看懂, 当用户访问是 首先执 ...
- codevs 1038 一元三次方程求解 NOIP2001提高组
题目链接:http://codevs.cn/problem/1038/ 题解: 嗯,exm?才知道二分隶属搜索专题…… 对-100到100枚举,按照题目中的提示,当当fi*fi+1<0时,二分深 ...
- 2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6153 A Secret KMP,思维
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6153 题意:给了串s和t,要求每个t的后缀在在s中的出现次数,然后每个次数乘上对应长度求和. 解法:关 ...
- Python的语言特性
1.Python的函数传参 Python中所有的变量都可以理解为内存中一个对象的“引用”,或者,也可以看似C中的void *的感觉.这里记住的是类型是属于对象的,而不是变量.对象分为两种: 可更改的: ...
- VPS性能综合测试(5):UnixBench工具介绍
UnixBench 介绍 UnixBench 是一个类 unix (Unix, BSD, Linux 等) 系统下的性能测试工具,它是一个开源工具.可以用于测试系统主机的性能. UnixBench 进 ...
- 初学者学习Javascript很吃力怎么办?到底该如何学习Js?
Js给初学者的印象总是那么的“杂而乱”,相信很多初学者都在找轻松学习Js的途径.在这里给大家总结一些学习Js的经验,希望能给后来的学习者探索出一条“轻松学习Js之路”. Js给人那种感觉的原因多半 ...
- RabbitMQ 基础知识
1. 背景 RabbitMQ 是一个由 erlang 开发的AMQP 开源实现,erlang语言天生具备高并发的特性,而且他的管理界面用起来十分方便. 基础概念 讲解基础概念的前面,我们先来整体构造一 ...