题解 CF995F 【Cowmpany Cowmpensation】
题意
给定一棵树,你要给每个点定一个
题解
由于我太菜不会插值,只好用容斥来做了。
我们考虑一个
但是,由于
计算出
由定义可知,
其中,系数
接着,我们就可以推出最终的容斥方程和答案:
这里,由于
代码
#include<bits/stdc++.h>
#define reg register
typedef long long ll;
using namespace std;
const int MN=3005;
const int mod=1e9+7;
int to[MN],nxt[MN],h[MN],cnt;
inline void ins(int s,int t){
to[++cnt]=t;nxt[cnt]=h[s];h[s]=cnt;
}
int n,m,f[MN][MN],s[MN][MN],g[MN],C[MN][MN],inv[MN];
void dfs(int st){
for(reg int i=h[st];i;i=nxt[i]){
dfs(to[i]);
for(reg int j=1;j<=n;j++)
f[st][j]=1ll*f[st][j]*s[to[i]][j]%mod;
}
for(reg int i=1;i<=n;i++)
s[st][i]=(s[st][i-1]+f[st][i])%mod;
}
int main(){
scanf("%d%d",&n,&m);
for(reg int i=2,x;i<=n;i++)scanf("%d",&x),ins(x,i);
for(reg int i=1;i<=n;i++)for(reg int j=1;j<=n;j++)f[i][j]=1;
dfs(1);C[0][0]=C[1][0]=C[1][1]=1;
for(reg int i=2;i<=n;i++){
C[i][0]=1;
for(reg int j=1;j<=i;j++)
C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
}
inv[0]=inv[1]=1;
for(reg int i=2;i<=n;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(reg int i=2;i<=n;i++)inv[i]=1ll*inv[i-1]*inv[i]%mod;
for(reg int i=1;i<=n;i++){
g[i]=f[1][i];
for(reg int j=1;j<i;j++)
g[i]=(g[i]-1ll*C[i-1][i-j]*g[j]%mod+mod)%mod;
}
reg int Ans=0;
for(reg int i=1;i<=min(n,m);i++){
reg int Res=inv[i];
for(reg int j=m-i+1;j<=m;j++)Res=1ll*Res*j%mod;
Ans=(Ans+1ll*Res*g[i]%mod)%mod;
}
printf("%d\n",Ans);
return 0;
}