Link
首先有一个很显然的(O(nd))的dp,设(f_{i,j})表示只考虑(i)的子树,(i)的权值(j)时的方案数。
转移是(f_{i,j}=prodlimits_{vin son_u}sumlimits_{k=1}^jf_{v,k}),前缀和优化即可。
不难发现(g_u(x)=f_{u,x})是一个不超过(n)次的多项式,因此dp时第二维的范围可以缩小至([0,n])。
然后Lagrange插值求出答案即可。
#include<cstdio>
const int N=3007,P=1000000007;
int fa[N],f[N][N],inv[N];
int read(){int x;scanf("%d",&x);return x;}
void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
int mul(int a,int b){return 1ll*a*b%P;}
int main()
{
int n=read(),d=read(),ans=0;inv[1]=1;
for(int i=2;i<=n;++i) inv[i]=mul(P-P/i,inv[P%i]);
for(int i=2;i<=n;++i) fa[i]=read();
for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) f[i][j]=1;
for(int i=n;i;--i)
{
for(int j=1;j<n;++j) inc(f[i][j+1],f[i][j]);
for(int j=1;j<=n;++j) f[fa[i]][j]=mul(f[fa[i]][j],f[i][j]);
}
for(int i=1;i<=n;++i)
{
int x=f[1][i];
for(int j=0;j<=n;++j) if(i^j) x=1ll*x*(d-j+P)%P*(i>j? inv[i-j]:P-inv[j-i])%P;
inc(ans,x);
}
printf("%d",ans);
}