列表

详情


NC17439. Endless Pallet

描述

There is a tree formed by N nodes. Initially, all the nodes are in white color. If there is at least one white node on the tree, Ash will randomly choose a path on the tree and dye all the nodes in the path black. Otherwise, Ash will stop dyeing and go home.

Given the tree, can you calculate the expected number of the paths Ash choose?

There are paths in total, that is, path from u to v and path from v to u are the same. It is okay to choose a path with no white node, but Ash will stop dyeing immediately when there are no white nodes on the tree.

输入描述

The input starts with one line containing exactly one integer T, which is the number of test cases.

Each test case starts with one line containing exactly one integer N, indicating the size of the tree.

Then followed by N lines, each consists of 2 numbers ui, vi, indicating the i-th edge of the tree is between ui and vi.
- 1 ≤ T ≤ 15.
- 1 ≤ N ≤ 50.
- 1 ≤ ui, vi ≤ n.

输出描述

For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1) and y is the expected number of the paths Ash choose.

In order to avoid floating point arithmetic, you are supposed to output y modulo 998244353, that means if the answer is equal to , you should output .

示例1

输入:

3
1
2
1 2
3
2 3
1 3

输出:

Case #1: 1
Case #2: 2
Case #3: 698771050

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 143ms, 内存消耗: 29164K, 提交时间: 2021-10-06 17:10:11

#include <bits/stdc++.h>

#define fp(i, a, b) for(int i = a, i##_ = (b) + 1; i < i##_; ++i)
using namespace std;
using ll = int64_t;
const int N = 52, M = N * (N + 1) / 2, P = 998244353;
int n, sz[N], inv[M], f[N][N][M][2], g[N][M][2];
vector<int> G[N];
#define MUL(a, b) ((ll) (a) * (b) % P)
#define ADD(a, b) (((a) += (b)) >= P ? (a) -= P : 0) // (a += b) %= P
int C2(int x) { return x * (x - 1) >> 1; }
void Merge(int a[N][M][2], int b[N][M][2], int A, int B) {
    fp(i, 0, A + B) memset(g[i], 0, 8 * (C2(A + B + 1) + 1));
    fp(i, 0, A) fp(j, 0, C2(A + 1)) fp(k, 0, 1) if (a[i][j][k])
        fp(x, 0, B) fp(y, 0, C2(B + 1)) fp(z, 0, 1) if (b[x][y][z])
            ADD(g[i ? i + x : 0][j + y + i * x][k ^ z], MUL(a[i][j][k], b[x][y][z]));
    fp(i, 0, A + B) memcpy(a[i], g[i], 8 * (C2(A + B + 1) + 1));
}
void dfs(int u, int p) {
    sz[u] = f[u][1][1][0] = f[u][0][0][1] = 1;
    for (auto v: G[u]) if (v != p)
        dfs(v, u), Merge(f[u], f[v], sz[u], sz[v]), sz[u] += sz[v];
}
void Solve() {
    fp(i, 1, n) G[i].clear();
    fp(i, 0, n) fp(j, 0, n) memset(f[i][j], 0, 8 * (C2(n + 1) + 1));
    for (int u, v, i = 1; i < n; ++i)
        scanf("%d%d", &u, &v),
        G[u].push_back(v), G[v].push_back(u);
    dfs(1, 0);
    ll ans = 0, s = C2(n + 1);
    fp(i, 0, n) fp(j, 0, s - 1) fp(k, 0, 1)
        ans += (k ? 1 : -1) * s * inv[s - j] % P * f[1][i][j][k] % P;
    printf("%lld\n", (ans % P + P) % P);
}
int main() {
    inv[1] = 1;
    fp(i, 2, M - 1) inv[i] = (ll) (P - P / i) * inv[P % i] % P;
    scanf("%*d");
    for (int i = 1; ~scanf("%d", &n); ++i)
        printf("Case #%d: ", i), Solve();
    return 0;
}

上一题