码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 543D Road Improvement(DP)

时间:2015-05-19 22:08:19      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:

题目链接

  

 

 


 

Solution

  比较明显的树形DP模型。

      首先可以先用一次DFS求出以1为根时,sum[i](以i为子树的根时,满足要求的子树的个数)。

      考虑将根从i变换到它的儿子j时,sum[i]产生的变化.

      在变化前sum[i]不为0时,可以用求逆元的方法求出新的sum[i].

      sum[i]为0时,就需要遍历i的新的儿子.

 

      官方的题解给出了一个比较好的做法是预处理i的儿子的前缀积,和后缀积.使用的时候只要去除相应的儿子.

 

技术分享
#include <bits/stdc++.h>
#define LL long long
using namespace std;

const int N = 200009;
const int MOD = int (1e9 + 7);

struct edge {
    int v, ne;
} E[N << 1];
int head[N], cnt;

LL sum[N], ans[N];

int n;

LL Quikpower (LL  Base, LL  Power)
{
    LL  k = 1;
    while ( Power > 0) {
        if (Power & 1) k = (k * Base) % MOD;
        Base = (Base * Base) % MOD;
        Power >>= 1;
    }
    return k;
}

inline void add (int u, int v)
{
    E[++cnt].v = v, E[cnt].ne = head[u];
    head[u] = cnt;
}

void dfs (int u, int from)
{
    sum[u] = 1;
    for (int i = head[u]; i; i = E[i].ne) {
        int v = E[i].v;
        if (v != from) {
            dfs (v, u);
            sum[u] = sum[u] * sum[v] % MOD;
        }
    }
    if (from != 0) ++sum[u];
}

void dfs2 (int u, int from)
{
    LL tem = 1;
    if (ans[from] != 0) {
        tem = ans[from] * Quikpower (sum[u], MOD - 2) % MOD + 1;
    }
    else {
        for (int i = head[from]; i; i = E[i].ne) {
            int v = E[i].v;
            if (v != u)
                tem = tem * sum[v] % MOD;
        }
        tem++;
    }
    sum[from] = tem;
    LL k = 1;
    for (int i = head[u]; i; i = E[i].ne) {
        int v = E[i].v;
        k = k * sum[v] % MOD;
    }
    ans[u] = k;

    int reset = sum[u];
    for (int i = head[u]; i; i = E[i].ne) {
        int v = E[i].v;
        if (v != from) {
            dfs2 (v, u);
            sum[u] = reset;
        }
    }
}
int main()
{
    ios::sync_with_stdio (0);

    cin >> n;
    for (int i = 2, x; i <= n; i++) {
        cin >> x;
        add (i, x), add (x, i);
    }

    dfs (1, 0);

    dfs2 (1, 0);

    for (int i = 1; i <= n; i++)
        cout << (ans[i] + MOD) % MOD << " ";
}
View Code

 

Codeforces 543D Road Improvement(DP)

标签:

原文地址:http://www.cnblogs.com/keam37/p/4515567.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!