Submission #579121

#TimeUsernameProblemLanguageResultExecution timeMemory
579121piOOEStar Trek (CEOI20_startrek)C++17
100 / 100
93 ms19484 KiB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 100000, mod = 1e9 + 7;

int add(int a, int b) {
    return a + b < mod ? a + b : a + b - mod;
}

int mul(int a, int b) {
    return a * (ll) b % mod;
}

int binp(int a, ll p) {
    int ans = 1;
    for (; p > 0; p >>= 1, a = mul(a, a)) {
        if (p & 1) {
            ans = mul(ans, a);
        }
    }
    return ans;
}

int sub(int a, int b) {
    return a >= b ? a - b : a - b + mod;
}

int inv(int a) {
    return binp(a, mod - 2);
}

vector<int> g[N];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    ll d;
    cin >> n >> d;
    for (int i = 1; i < n; ++i) {
        int a, b;
        cin >> a >> b;
        --a, --b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vector<bool> dp(n);
    vector<int> cntLoosing(n), c(n), total(n), only_loosing(n);

    function<void(int, int)> dfs1 = [&](int v, int p) {
        dp[v] = false;
        cntLoosing[v] = 0;
        for (int to: g[v]) {
            if (to != p) {
                dfs1(to, v);
                if (!dp[to]) {
                    only_loosing[v] += c[to];
                    ++cntLoosing[v];
                    dp[v] = true;
                }
                total[v] += c[to];
            }
        }
        if (cntLoosing[v] > 1) {
            c[v] = 0;
        } else if (cntLoosing[v] == 1) {
            c[v] = only_loosing[v];
        } else {
            c[v] = total[v] + 1;
        }
    };

    function<void(int, int)> dfs2 = [&](int v, int p) {
        dp[v] = cntLoosing[v];
        if (cntLoosing[v] > 1) {
            c[v] = 0;
        } else if (cntLoosing[v] == 1) {
            c[v] = only_loosing[v];
        } else {
            c[v] = total[v] + 1;
        }
        for (int to: g[v]) {
            if (to != p) {
                int gg = c[to];
                total[v] -= gg;
                bool zz = dp[to];
                if (!dp[to]) {
                    --cntLoosing[v];
                    only_loosing[v] -= gg;
                }
                int now;
                if (cntLoosing[v] > 1) {
                    now = 0;
                } else if (cntLoosing[v] == 1) {
                    now = only_loosing[v];
                } else {
                    now = total[v] + 1;
                    dp[to] = true;
                    ++cntLoosing[to];
                    only_loosing[to] += now;
                }
                total[to] += now;
                dfs2(to, v);

                total[v] += gg;

                if (!zz) {
                    cntLoosing[v] += 1;
                    only_loosing[v] += gg;
                }

            }
        }

    };

    dfs1(0, -1);

    dfs2(0, -1);

    int E = 0, L = 0;

    for (int i = 0; i < n; ++i) {
        if (dp[i]) {
            E = add(E, c[i]);
        } else {
            L += 1;
            E = sub(E, c[i]);
        }
    }

    int a = mul(n, n);

    int x = mul(L, mul(sub(binp(a, d), binp(E, d)), inv(sub(a, E))));

    int ans;

    if (dp[0]) {
        ans = mul(x, c[0]);
    } else {
        ans = sub(binp(a, d), mul(x, c[0]));
    }

    cout << sub(binp(a, d), ans);
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...