CodeForces 543d Road Improvement

Road Improvement

Time Limit: 2000ms
Memory Limit: 262144KB
This problem will be judged on CodeForces. Original ID: 543D
64-bit integer IO format: %I64d      Java class name: (Any)

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 from1 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).

 

Input

The first line of the input contains a single integer n (2 ≤ n ≤ 2·105) — the number of cities in the country. Next line contains n - 1 positive integers p2, p3, p4, ..., pn (1 ≤ pi ≤ i - 1) — the description of the roads in the country. Number pi means that the country has a road connecting city pi and city i.

 

Output

Print n integers a1, a2, ..., an, where ai is the sought number of ways to improve the quality of the roads modulo 1 000 000 007 (109 + 7), if the capital of the country is at city number i.

 

Sample Input

Input
3
1 1
Output
4 3 3
Input
5
1 2 3 4
Output
5 8 9 8 5

Source

 
解题:树形dp
 
dp[u]表示以u为根的方案数,dp[u] = (dp[v]+1)*(dp[v2]+1)...
 
为什么加1?因为如果u到v的路修的话就是dp[v],如果不修,那么只有1种方案,子树都要修
 
那么我们如何计算任意点位根的数量呢
 
假设当前早在v 其父亲为u dp2[u]表示以u为根倒回去的方案数,那么以为根的方案数是多少?
 
很显然我们要计算出v的兄弟的方案数,(dp[v]+1)*(dp[v2]+1)...
 
乘上u倒回去的方案数 
 
就是去掉v这棵树 以u为根的方案数,
 现在加上v
u到v的边可以修,那么就是前面的方案数,如果不修,那只有一种方案
 
也就是说前面的积+1后
乘以以v为根的方案数dp[v]。。就是以v为首都的可行方案数
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 200010;
 5 vector<int>g[maxn];
 6 LL dp[maxn],dp2[maxn];
 7 const LL mod = 1000000007;
 8 void dfs(int u,int fa){
 9     dp[u] = 1;
10     for(int i = g[u].size()-1; i >= 0; --i){
11         if(g[u][i] == fa) continue;
12         dfs(g[u][i],u);
13         dp[u] = dp[u]*(dp[g[u][i]]+1)%mod;
14     }
15 }
16 LL L[maxn],R[maxn];
17 void dfs2(int u,int fa){
18     int m = g[u].size();
19     L[0] = 1;
20     R[m - 1] = dp2[u];
21     for(int i = 1; i < m; ++i)
22         L[i] = L[i-1]*(dp[g[u][i-1]]+1)%mod;
23     for(int i = m-2; i >= 0; --i)
24         R[i] = R[i+1]*(dp[g[u][i+1]]+1)%mod;
25     for(int i = 0; i < m; ++i){
26         if(g[u][i] == fa) continue;
27         dp2[g[u][i]] = (L[i]*R[i] + 1)%mod;
28     }
29     for(int i = 0; i < m; ++i){
30         if(g[u][i] == fa) continue;
31         dfs2(g[u][i],u);
32     }
33 }
34 int main(){
35     int n,o;
36     scanf("%d",&n);
37     for(int i = 2; i <= n; ++i){
38         scanf("%d",&o);
39         g[o].push_back(i);
40     }
41     dp2[1] = 1;
42     dfs(1,0);
43     dfs2(1,0);
44     for(int i = 1; i <= n; ++i)
45         cout<<dp2[i]*dp[i]%mod<<(i == n?"\n":" ");
46     return 0;
47 }
View Code

 

posted @ 2015-07-21 10:33  狂徒归来  阅读(346)  评论(0编辑  收藏  举报