2017ccpc Hangzhou D-Master of Random (hdu6267 expectation + find the law)

 

Title:

There are n points, and each point corresponds to a weight. Now we need to build a tree. For the i-th point, randomly select a parent node from points [0, i-1], and find the weight of all subtrees in the tree. And expectations

Ideas:

No idea, hard to find the rules

When n = 4:

Found that point 0 contributed 6 times, 6 = 3!

Point 1 contributed 12 times, 12 = 3! + 3! / 1

Point 2 contributed 15 times, 15 = 3! + 3! / 1 + 3! / 2

Point 3 contributed 17 times, 17 = 3! + 3! / 1 + 3! / 2 + 3! / 3

So the number of contributions of point x is n! + n! / 1 + n! / 2 + ..... + n! / x

Don’t forget that the last thing you want is expectation, divide by n! 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
const double eps = 1e-11;
const int N = 1e5 + 10;

ll fac[N], fun[N];

ll qpow(ll a, ll b) {
    ll ans = 1;
    a %= mod;
    while(b) {
        if(b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans % mod;
}

void init() {
    fac[0] = 1;
    for(int i = 1; i < N; ++i)
        fac[i] = fac[i - 1] * i % mod;
    fun[0] = 1;
    for(int i = 1; i < N; ++i)
        fun[i] = (fun[i - 1] + qpow(i, mod - 2)) % mod;
}

int main() {
    init();
    int t, n;
    ll a;
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        ll ans = 0;
        for(int i = 0; i < n; ++i) {
            scanf("%lld", &a);
            ans = (ans + fun[i] * a % mod) % mod;
        }
        printf("%lld\n", ans * qpow(fac[n], mod - 2) % mod * fac[n - 1] % mod);
    }
    return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_43871207/article/details/109563414