Soluție HackerRank pentru Magic Number Tree, subdomeniul Probability, în C++14. Include cerința formatată, exemple, explicația pașilor și cod sursă.

  • Problemă: Magic Number Tree
  • Domeniu: Probability
  • Limbaj: C++14

Challenge: Magic Number Tree

Subdomeniu: Probability (probability)

Scor cont: 60.0 / 60

Submission status: Accepted

Submission score: 1.0

Submission ID: 464756770

Limbaj: cpp14

Link challenge: https://www.hackerrank.com/challenges/james-tree/problem

Cerință

James has a tree with n nodes n-1 edges where the i-th edge has a length, w_i. He wants to play a game involving n moves. During each move, he performs the following steps:

* Randomly chooses some node x_i from the tree. Each node has an equal probability of being chosen.
* Calculates the distance from node x_i to each node reachable from x_i using one or more edges.
* Deletes node x_i.

For example, the diagram below shows what happens when we choose a random node and delete it from the tree:

![image](https://s3.amazonaws.com/hr-challenge-images/0/1483093526-099fca06d4-magic11.png)

After n moves, the tree is empty and the game ends.

James defines the magic number, m, as the sum of all numbers calculated in step 2 of each move. Let E_m be the [expected value](https://en.wikipedia.org/wiki/Expected_value) of m.

Give the tree's edges and their respective lengths, calculate and the print the value of (E_m × n!) text{mod} (10^9+9). It is guaranteed that E_m × n! is an integer.

Note

Due to a bug in the system, you might see ``accepted`` verdict in this problem even if you don't pass all the test cases. Please ignore that verdict, only the score you get is important in the ranklist.

Input Format

The first line contains an integer, n, denoting the number of nodes.
Each of the n-1 subsequent lines contains three space-separated integers describing the respective values of u_i, v_i, and w_i, meaning that there is an edge of length w_i connecting nodes u_i and v_i.

Output Format

Print a single integer denoting the value of (E_m × n!) text{mod} (10^9+9).

Constraints

* 1 ≤ n ≤ 5000
* 1 ≤ u_i,v_i ≤ n
* 1 ≤ w_i ≤ 10^9

Subtasks

* For 30% of the max score n ≤ 10
* For 60% of the max score n ≤ 400

Cod sursă

#include <bits/stdc++.h>
using namespace std;

static const long long MOD = 1000000009LL;

long long modPow(long long a, long long e) {
    long long r = 1 % MOD;
    a %= MOD;
    while (e > 0) {
        if (e & 1) r = (__int128)r * a % MOD;
        a = (__int128)a * a % MOD;
        e >>= 1;
    }
    return r;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<vector<pair<int, long long>>> g(n + 1);
    for (int i = 0; i < n - 1; ++i) {
        int u, v;
        long long w;
        cin >> u >> v >> w;
        g[u].push_back({v, w});
        g[v].push_back({u, w});
    }

    vector<long long> inv(n + 1, 1);
    for (int i = 1; i <= n; ++i) inv[i] = modPow(i, MOD - 2);

    long long pairSum = 0; // sum over unordered pairs of 2*dist/(path_nodes)

    vector<int> parent(n + 1), hops(n + 1);
    vector<long long> dist(n + 1);

    for (int s = 1; s <= n; ++s) {
        // Iterative DFS from source s.
        vector<int> st;
        st.reserve(n);
        st.push_back(s);
        parent[s] = 0;
        hops[s] = 0;
        dist[s] = 0;

        while (!st.empty()) {
            int u = st.back();
            st.pop_back();

            for (const auto &e : g[u]) {
                int v = e.first;
                long long w = e.second;
                if (v == parent[u]) continue;
                parent[v] = u;
                hops[v] = hops[u] + 1;
                dist[v] = dist[u] + w;
                st.push_back(v);
            }
        }

        for (int v = s + 1; v <= n; ++v) {
            int pathNodes = hops[v] + 1;
            long long dmod = dist[v] % MOD;
            long long add = (__int128)2 * dmod % MOD;
            add = (__int128)add * inv[pathNodes] % MOD;
            pairSum += add;
            if (pairSum >= MOD) pairSum -= MOD;
        }
    }

    long long fact = 1;
    for (int i = 2; i <= n; ++i) fact = (__int128)fact * i % MOD;

    long long ans = (__int128)pairSum * fact % MOD;
    cout << ans << '\n';
    return 0;
}
HackerRank Probability – Magic Number Tree