zoukankan      html  css  js  c++  java
  • 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?"
    ":" ");
    46     return 0;
    47 }
    View Code
  • 相关阅读:
    Delphi 中流的使用
    关于 Delphi 中流的使用(9) 分割与合并文件的函数
    基于Windows字库的点阵数据提取方法
    Oracle 后台进程介绍
    面试-MySQL
    怎样预置桌面上的应用程序图标、快捷方式图标或者窗体小部件?
    配置 Phpstorm + Xdebug + xampp
    [jQuery] 选择器和事件
    数据挖掘算法学习(四)PCA算法
    基础数位DP小结
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4663677.html
Copyright © 2011-2022 走看看