【题解】Partial Virtual Trees
TallBanana · · 题解
题面:Partial Virtual Trees
首先发现是真子集的限制,考虑使限制变为子集的限制。考虑答案数组
对于求
对于
为什么考虑这两种情况?对于
那么转移方程有:
-
F_{u,i}\leftarrow \prod_{v\in son_u}\sum_{j=1}^iF_{v,j} -
F_{u,i}\leftarrow \sum_{del=1}^{i-1}\sum_{v\in son_u}F_{v,i}\prod_{w\in son_u,w\neq v}\sum_{t=1}^{del}F_{w,t}
其中,
再看
求出了
code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N=2e3+10;
LL n,P,f[N][N],pre[N],suf[N],g[N][N],sum[N][N];
vector<LL> e[N];
void dfs(LL u,LL fa)
{
vector<LL> son;
for(auto v:e[u]) if(v!=fa)
dfs(v,u),son.push_back(v);
for(int i=1;i<n;i++)
{
pre[0]=1; suf[son.size()+1]=1;
for(int j=1;j<=son.size();j++) pre[j]=pre[j-1]*sum[son[j-1]][i]%P;
for(int j=son.size();j>=1;j--) suf[j]=suf[j+1]*sum[son[j-1]][i]%P;
for(int j=1;j<=son.size();j++) g[j][i]=(pre[j-1]*suf[j+1]%P+g[j][i-1])%P;
}
for(int i=1;i<n;i++)
{
f[u][i]=1;
for(auto v:son) f[u][i]=f[u][i]*sum[v][i]%P;
if(u!=1) for(int j=1;j<=son.size();j++)
f[u][i]=(f[u][i]+f[son[j-1]][i]*g[j][i-1]%P)%P;
sum[u][i]=(sum[u][i-1]+f[u][i])%P;
}
}
int main()
{
scanf("%lld%lld",&n,&P);
for(int i=1;i<n;i++)
{
LL u,v;
scanf("%lld%lld",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1,0);
for(int i=0;i<=n;i++)
for(int j=0;j<=i;j++)
if(j==0||j==i) sum[i][j]=1;
else sum[i][j]=(sum[i-1][j-1]+sum[i-1][j])%P;
pre[0]=0;
for(int i=1;i<n;i++)
{
pre[i]=f[1][i];
for(int j=1;j<i;j++) pre[i]=(pre[i]-sum[i][j]*pre[j]%P+P)%P;
printf("%lld ",pre[i]);
}
return 0;
}