题意:给一棵树,一次操作定义为删掉一条树边再加一条边,并且满足加完边后这还是一棵树,问在进行不超过$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的更多相关文章

随机推荐

  1. [POI2004] SZP (贪心+拓扑排序)

    [问题描述] Byteotian 中央情报局(BIA) 雇佣了许多特工. 他们每个人的工作就是监视 另一名特工. Byteasar 国王需要进行一次秘密行动,所以他要挑选尽量多的信得过的特工. 但 是 ...

  2. Different Integers(牛客多校第一场+莫队做法)

    题目链接:https://www.nowcoder.com/acm/contest/139/J 题目: 题意:给你n个数,q次查询,对于每次查询得l,r,求1~l和r~n元素得种类. 莫队思路:1.将 ...

  3. Atlantis(POJ1151+线段树+扫描线)

    题目链接:http://poj.org/problem?id=1151 题目: 题意:求所有矩形的面积,重合部分只算一次. 思路:扫描线入门题,推荐几篇学扫描线的博客: 1.http://www.cn ...

  4. 《Applying Deep Learning to Answer Selection: A Study And an Open Task》文章理解小结

    本篇论文是2015年的IBM watson团队的. 论文地址: 这是一篇关于QA问题的一篇论文: 相关论文讲解1.https://www.jianshu.com/p/48024e9f7bb22.htt ...

  5. 分布式实时日志分析解决方案ELK部署架构

    一.概述 ELK 已经成为目前最流行的集中式日志解决方案,它主要是由Beats.Logstash.Elasticsearch.Kibana等组件组成,来共同完成实时日志的收集,存储,展示等一站式的解决 ...

  6. CART算法(转)

    来源:http://www.cnblogs.com/pinard/p/6053344.html 作者:刘建平Pinard 对于C4.5算法,我们也提到了它的不足,比如模型是用较为复杂的熵来度量,使用了 ...

  7. MS16-032提权正确方法

    原版MS16-032提权会Spawn一个System Shell出来,只能通过Remote Desktop获取.这里修改exploit,直接反弹Shell.注意MS16-032依赖 thread ha ...

  8. oracle中有关表的操作

    在Oracle中查看所有的表: select * from tab/dba_tables/dba_objects/cat; 看用户建立的表 : select table_name from user_ ...

  9. 升级OS10.11系统后 Xcode6.4的变化少了个按钮 could not launch “Xcode” Xcode 插件安装

    升级OS10.11系统后 Xcode6.4的变化少了个按钮 could not launch “Xcode”  Xcode 插件安装 A:  升级10.11后Xcode 左上角模拟器选择菜单不在了   ...

  10. git学习笔记三

    1.每个分支的历史版本维护信息位置是.git/logs/refs/heads/master,这个位置的信息是文本文件,不是引用. harvey@harvey-Virtual-Machine:~/dem ...