题意:给一棵树,一次操作定义为删掉一条树边再加一条边,并且满足加完边后这还是一棵树,问在进行不超过$k$次操作后能构造出多少种不同的树
首先...矩阵树定理在边有边权的时候同样适用,这时可以把它看成重边,此时直接按原方法求得的是所有生成树的边权乘积之和
所以我们可以把这棵树补成一个完全图,令补上去的边边权为$x$,那么答案就是求出来的多项式的$0\cdots k$次系数之和
直接带着多项式做当然不行,所以我们就用单位根作为$x$,求值后IDFT回去即可
我的代码在$k=n-1$时会错...?
#include#include #include 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 >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 >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