[cf1097G]Vladislav and a Great Legend
记$S(n,m)$为第二类斯特林数,表示将$n$个不同的球放入$m$个相同的盒子中,不允许有空的方案数,则有转移式$S(n,m)=S(n-1,m-1)+m\cdot S(n-1,m)$(考虑最后一个球)
对于$m^{k}$,即将$k$个不同的球放入$m$个不同的盒子中,允许有空的方案数,枚举空盒的数目与盒子的选择,那么即有$m^{k}=\sum_{i=0}^{k}i!\cdot c(m,i)\cdot S(k,i)$
代入题中,即$\sum_{X}f(X)^{k}=\sum_{i=0}^{k}i!\cdot S(k,i)\cdot \sum_{X}c(f(X),i)$,后者即从虚树中选择$i$条边,考虑dp
设$f[k][i]=\sum_{X的虚树根在k子树中}c(f(X),i)$,转移枚举儿子$son$并分类讨论:
1.$lca$在$son$这棵子树中,$(k,son)$不能选,即$f[k][i]+=f[son][i]$
2.否则,类似背包的转移,枚举原来选的边,$(k,son)$任意,即$f[k][i+j+0/1]+=f[k][i]\cdot f[son][j]$
但这样还有一个问题,在第2种转移中,如果初始lca不为$k$,但加入另一棵子树后lca必然为$k$,那么无法考虑原来的子树到根的路径
考虑强制$(k,son)$都可以选,那么第1类转移变为$f[k][i]+=f[son][i]+f[son][i-1]$,但这样答案应该是每一次乘积的和,即保证了这些$(k,son)$的边都可以选
这样的复杂度看上去是$o(nk^{2})$的,但注意到$i$的范围是$\min(sz,k)$,简单分析可以发现是$o(nk)$的
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define mod 1000000007 5 struct ji{ 6 int nex,to; 7 }edge[N<<1]; 8 int E,n,m,x,y,ans,head[N],sz[N],g[205],s[205][205],sum[205],f[N][205]; 9 void add(int x,int y){ 10 edge[E].nex=head[x]; 11 edge[E].to=y; 12 head[x]=E++; 13 } 14 void dfs(int k,int fa){ 15 sz[k]=f[k][0]=1; 16 for(int i=head[k];i!=-1;i=edge[i].nex) 17 if (edge[i].to!=fa){ 18 int v=edge[i].to; 19 dfs(v,k); 20 memcpy(g,f[k],sizeof(g)); 21 for(int j=0;j<=sz[v];j++)f[k][j]=(f[k][j]+f[v][j])%mod; 22 for(int j=1;j<=sz[v];j++)f[k][j]=(f[k][j]+f[v][j-1])%mod; 23 for(int j=0;j<=sz[k];j++) 24 for(int l=0;(l<=sz[v])&&(j+l<=m);l++){ 25 f[k][j+l]=(f[k][j+l]+1LL*g[j]*f[v][l])%mod; 26 sum[j+l]=(sum[j+l]+1LL*g[j]*f[v][l])%mod; 27 f[k][j+l+1]=(f[k][j+l+1]+1LL*g[j]*f[v][l])%mod; 28 sum[j+l+1]=(sum[j+l+1]+1LL*g[j]*f[v][l])%mod; 29 } 30 sz[k]=min(sz[k]+sz[v],m); 31 } 32 } 33 int main(){ 34 scanf("%d%d",&n,&m); 35 memset(head,-1,sizeof(head)); 36 for(int i=1;i<n;i++){ 37 scanf("%d%d",&x,&y); 38 add(x,y); 39 add(y,x); 40 } 41 s[0][0]=1; 42 for(int i=1;i<=m;i++) 43 for(int j=1;j<=m;j++)s[i][j]=(s[i-1][j-1]+1LL*j*s[i-1][j])%mod; 44 dfs(1,0); 45 int fac=1; 46 for(int i=1;i<=m;i++){ 47 fac=1LL*fac*i%mod; 48 ans=(ans+1LL*fac*s[m][i]%mod*sum[i])%mod; 49 } 50 printf("%d",ans); 51 }