zoukankan      html  css  js  c++  java
  • Codeforces 543D Road Improvement(DP)

    题目链接

      


    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
  • 相关阅读:
    php 给图片添加文字水印 可控制位置,旋转,多行文字
    太多的用户请求,网站出现了504
    这些问题,你注意了吗?
    ubuntu 系统环境配置记录
    node.js开发指南中出现的问题 has no method 'router'解决办法
    在nodejs express 中使用session的功能
    更改窗口大小,重新加载微博发布框
    原生js控制audio标签自动播放
    利用css3转换transform画五星红旗
    css3+js旗帜飘动
  • 原文地址:https://www.cnblogs.com/keam37/p/4515567.html
Copyright © 2011-2022 走看看