• 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
  • 相关阅读:
    2020牛客多校第十场C-Decrement on the Tree
    2020牛客多校第九场B- Groundhog and Apple Tree
    2020牛客多校第九场J-The Escape Plan of Groundhog
    2020牛客多校第九场E-Groundhog Chasing Death
    2020牛客多校第八场E-Enigmatic Partition
    2020牛客多校第八场A-All Star Game
    2020牛客多校第八场I-Interseting Computer Game
    2020牛客多校第七场H-Dividing
    2020牛客多校第七场J-Pointer Analysis
    2020牛客多校第七场C-A National Pandemic
  • 原文地址:https://www.cnblogs.com/keam37/p/4515567.html
Copyright © 2020-2023  润新知