因为$E(a + b) = E(a) + E(b)$,考虑分拆按位算答案。
令$f(u,bit)$为u到n,bit位为一的期望。发现有后效性,可以高斯消元求解。
则$ans$为f函数u=1时每一位的乘积乘上2的bit次方。
C++ 代码
// Program written by Liu Zhaozhou ~~~
const int Maxn = 105, Maxm = 2e5 + 5;
int n, m, deg[Maxn], cnt = 0, head[Maxn], ver[Maxm], nxt[Maxm], edge[Maxm];
inline void AddEdge(int u, int v, int w) {
ver[++cnt] = v, edge[cnt] = w, nxt[cnt] = head[u], head[u] = cnt;
}
double a[Maxn][Maxn];
inline void GaussJordan(void) {
for (int i = 1, r = 1; i <= n; r = ++i) {
for (int j = i + 1; j <= n; j++) if (abs(a[j][i]) > abs(a[r][i])) r = j;
if (r != i) for (int j = 1; j <= n + 1; j++) swap(a[r][j], a[i][j]);
for (int j = 1; j <= n; j++) {
if (i == j) continue; double tmp = a[j][i] / a[i][i];
for (int k = i + 1; k <= n + 1; k++) a[j][k] -= a[i][k] * tmp;
}
} for (int i = 1; i <= n; i++) a[i][n + 1] /= a[i][i];
}
signed main(void) {
// file("");
read(n), read(m);
for (int i = 1, u, v, w; i <= m; i++) {
read(u), read(v), read(w);
if (u == v) { AddEdge(u, v, w); deg[u]++; }
else { AddEdge(u, v, w), AddEdge(v, u, w); deg[u]++; deg[v]++; }
}
double ans = 0;
for (int s = 30; ~s; s--) { Ms(a, 0);
for (int u = 1; u < n; u++) {
a[u][u] = -deg[u];
for (int i = head[u], w; i; i = nxt[i]) {
w = (edge[i] >> s) & 1;
if (w) a[u][ver[i]] -= 1, a[u][n + 1] -= 1;
else a[u][ver[i]] += 1;
}
} a[n][n] = 1; GaussJordan();
ans += (1 << s) * a[1][n + 1];
} printf("%.3lf\n", ans);
// fwrite(pf, 1, o1 - pf, stdout);
return 0;
}
/**/