zoukankan      html  css  js  c++  java
  • codeforces 543D

    题解:

    考虑dp[u][0/1]表示u的子树中有没有坏边的方案数,

    dp[u][0] = 1(显然必须全是好边)

    dp[u][1] = ∏ (dp[v][0] * 2 + dp[v][1]) - 1 (-1是全是好边的情况)

    然后我们考虑这个dp[u][0]并没有必要单独设出来

    令f[u] = dp[u][0] + dp[u][1]

    则f[u] = ∏ (1 + f[v])

    显然f[1]可以求出来了

    这个就是ans[1]

    然后再扫一遍,记录从根到u的信息val = ans[u] / (1 + f[v])

    这样ans[v] = f[u] * (val + 1)(将来自父亲的那一块也看成子树)

    然后这里 /(1 + f[v])求逆元是错的

    因为 1 + f[v] == mod 时就GG了

    所以考虑维护前缀和、后缀和

    每次乘一下就可以了

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define maxn 200005
     4 using namespace std;
     5 const ll mod = 1000000007;
     6 int n;
     7 vector<int> g[maxn];
     8 ll f[maxn],ans[maxn];
     9 ll fastpow(ll a,ll p)
    10 {
    11     ll res=1;
    12     while(p)
    13     {
    14         if(p&1)res=res*a%mod;
    15         a=a*a%mod;p>>=1;
    16     }
    17     return res;
    18 }
    19 ll inv(ll x)
    20 {
    21     return fastpow(x,mod-2);
    22 }
    23 void dfs(int u)
    24 {
    25     f[u]=1;
    26     for(int i=0;i<g[u].size();++i)
    27     {
    28         int v=g[u][i];
    29         dfs(v);
    30         f[u]=f[u]*(1+f[v])%mod;
    31     }
    32 }
    33 void dfs2(int u,ll val)
    34 {
    35     if(u==1)ans[u]=f[u];
    36     else ans[u]=f[u]*(val+1)%mod;
    37     int sz=g[u].size();
    38     vector<ll> pre(sz+1,0),suf(sz+1,0);
    39     pre[0]=1,suf[sz]=1;
    40     for(int i=1;i<=sz;++i)
    41     {
    42         int v=g[u][i-1];
    43         pre[i]=pre[i-1]*(1+f[v])%mod;
    44     }
    45     for(int i=sz-1;i>=0;--i)
    46     {
    47         int v=g[u][i];
    48         suf[i]=suf[i+1]*(1+f[v])%mod;
    49     }
    50     for(int i=0;i<sz;++i)
    51     {
    52         int v=g[u][i];
    53         dfs2(v,(val+1)*pre[i]%mod*suf[i+1]%mod);
    54     }
    55 }
    56 int main()
    57 {
    58     scanf("%d",&n);
    59     for(int x,i=2;i<=n;++i)
    60     {
    61         scanf("%d",&x);
    62         g[x].push_back(i);
    63     }
    64     dfs(1);
    65     dfs2(1,0);
    66     for(int i=1;i<=n;++i)printf("%I64d ",ans[i]);
    67     return 0; 
    68 }
    View Code
  • 相关阅读:
    智能家居测试思路
    Linux中,&和&&,|和||
    Eclipse设置保存代码时自动格式化代码
    Eclipse常用快捷键
    Eclipse设置快捷出现函数
    Eclipse设置代码背景色
    PDF转换成Word后乱码怎么办?
    Able2Extract快捷键汇总整理
    安装并激活Parallels Desktop商业版
    想在Mac上使用CAD?
  • 原文地址:https://www.cnblogs.com/uuzlove/p/10514136.html
Copyright © 2011-2022 走看看