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
  • 相关阅读:
    Burpsuite intruder模块 越过token进行爆破,包含靶场搭建
    burpsuiteb windows10 下载与安装
    sqlmap的命令总结
    Vue.js与jQuery混用
    IE低版本cors跨域请求
    window.open打开网址被拦截
    一图一知之python3数据类型
    一图一知-vue强大的slot
    一图一知-强大的js数组
    windows中git输错密码后不能修改问题
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4663677.html
Copyright © 2011-2022 走看看