The country has n cities and n - 1 bidirectional roads, it is possible to get from every city to any other one if you move only along the roads. The cities are numbered with integers from 1 to n inclusive.
All the roads are initially bad, but the government wants to improve the state of some roads. We will assume that the citizens are happy about road improvement if the path from the capital located in city x to any other city contains at most one bad road.
Your task is — for every possible x determine the number of ways of improving the quality of some roads in order to meet the citizens’ condition. As those values can be rather large, you need to print each value modulo 1 000 000 007 (109 + 7).
设f[x]表示以x为根的子树恰好符合要求的方案数。
f[x]=(f[son[1]]+1)*(f[son[2]]+1)…同时题目还要求换根,所以我们记g[x]表示从x向上延伸的方案数(就是整棵树除了x的子树以外的部分),由父亲来更新儿子。假设x为第i个儿子,则g[x]=(f[son[1]]+1)(f[son[2]]+1)…(f[son[i-1]]+1)(f[son[i+1]]+1)…g[fa]
最终的答案是ans[i]=g[i]*f[i].
Tips:叶子节点的f值是1,根节点的g值是1.
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn=200000+10;
const int md=1000000007;
long long f[maxn],h[maxn],pre[maxn],suf[maxn];
int n;
vector<int> g[maxn];
void dfs1(int p)
{
f[p]=1;
for(int i=0;i<g[p].size();i++)
{
int v=g[p][i];dfs1(v);
f[p]=(f[p]*(f[v]+1))%md;
}
}
void dfs2(int p)
{
if(!g[p].size()) return;
pre[0]=1;
for(int i=1;i<=g[p].size()-1;i++)
{
int v=g[p][i-1];
pre[i]=(pre[i-1]*(f[v]+1))%md;
}
suf[g[p].size()-1]=1;
for(int i=g[p].size()-2;i>=0;i--)
{
int v=g[p][i+1];
suf[i]=(suf[i+1]*(f[v]+1))%md;
}
for(int i=0;i<g[p].size();i++)
{
int v=g[p][i];
h[v]=(h[p]*suf[i]%md*pre[i]%md)%md;
h[v]=(h[v]+1)%md;
}
for(int i=0;i<g[p].size();i++) dfs2(g[p][i]);
}
int main()
{
scanf("%d",&n);
for(int i=2;i<=n;i++)
{
int x;scanf("%d",&x);
g[x].push_back(i);
}
dfs1(1);h[1]=1;dfs2(1);
for(int i=1;i<=n;i++)
{
long long ans=h[i]*f[i]%md;
printf("%I64d ",ans);
}
return 0;
}