Problem
Define the unique ornamental coloring of a rooted tree* as the following vertex coloring:
- A vertex v v v is colored white if the number of vertices in the subtree† rooted at v v v is even;
- Otherwise, v v v is colored black.
On his quest to conquer a forest of Christmas trees, Yuuki encountered an ornamentally colored tree T T T with n n n vertices labeled from 1 1 1 to n n n, rooted at vertex 1 1 1.
Yuuki considers the tree conquered if and only if at least one of the following conditions holds:
- There are no white vertices in the tree, or
- There exists some vertex v v v such that all white vertices lie on the simple path from the root 1 1 1 to v v v.
To conquer the tree, Yuuki can apply the following operation on T T T an arbitrary number of times (possibly zero):
- First, choose a vertex w w w that is colored white and is not the root of T T T. Let p w p_w pw be the parent of w w w.
- Then, remove the edge connecting p w p_w pw and w w w, and add an edge between any two vertices such that T T T remains a tree.
- Finally, recolor the vertices of T T T such that it is ornamentally colored. Note that T T T is always rooted at vertex 1 1 1.
Compute the number of distinct‡ conquered trees that Yuuki can construct by applying the above operation an arbitrary number of times on T T T. Since the answer may be large, output it modulo 998 244 353 998\ 244\ 353 998 244 353.
Note that Yuuki cannot stop midway through an operation (in particular, he must recolor the tree before checking if it is conquered). Additionally, Yuuki is allowed to apply the operation even if the tree is already conquered.
Input
Each test contains multiple test cases. The first line contains the number of test cases t t t ( 1 ≤ t ≤ 10 4 1 \le t \le 10^4 1≤t≤104). The description of the test cases follows.
The first line of each test case contains a single integer n n n ( 2 ≤ n ≤ 2 ⋅ 10 5 2 \le n \le 2 \cdot 10^5 2≤n≤2⋅105) --- the number of vertices in T T T.
Then n − 1 n - 1 n−1 lines follow, the i i i-th line containing two integers u i u_i ui and v i v_i vi ( 1 ≤ u i < v i ≤ n 1 \le u_i < v_i \le n 1≤ui<vi≤n) --- the two vertices that the i i i-th edge connects.
It is guaranteed that the given edges form a tree.
It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 10 5 2 \cdot 10^5 2⋅105.
Output
For each test case, output a single integer --- the number of distinct conquered trees that can be constructed from T T T, modulo 998 244 353 998\,244\,353 998244353.
Translation
将有根树*的唯一"装饰性着色(ornamental coloring)"定义为如下顶点着色方式:
- 如果以顶点 v v v 为根的子树†中的顶点数为偶数,则 v v v 被染成白色;
- 否则, v v v 被染成黑色。
在征服圣诞树森林的旅途中,Yuuki 遇到了一棵装饰性着色的树 T T T,它有 n n n 个编号为 1 1 1 到 n n n 的顶点,且以顶点 1 1 1 为根。
当且仅当满足以下至少一个条件时,Yuuki 认为这棵树被"征服(conquered)"了:
- 树中没有白色顶点,或者
- 存在某个顶点 v v v,使得所有白色顶点都位于从根节点 1 1 1 到 v v v 的简单路径上。
为了征服这棵树,Yuuki 可以对 T T T 执行任意次数(可能为零次)以下操作:
- 首先,选择一个颜色为白色且不是 T T T 的根节点的顶点 w w w。令 p w p_w pw 为 w w w 的父节点。
- 然后,断开连接 p w p_w pw 和 w w w 的边,并在任意两个顶点之间添加一条边,使得 T T T 保持为一棵树。
- 最后,重新对 T T T 的顶点进行装饰性着色。注意 T T T 始终以顶点 1 1 1 为根。
计算 Yuuki 通过对 T T T 应用上述操作任意次数可以构建的不同的‡被征服树的数量。由于答案可能很大,请对 998 244 353 998\ 244\ 353 998 244 353 取模后输出。
注意,Yuuki 不能在操作中途停止(特别是,他必须在检查树是否被征服之前重新着色)。此外,即使树已经被征服,Yuuki 也可以继续执行操作。
输入
每个测试包含多个测试用例。第一行包含测试用例的数量 t t t ( 1 ≤ t ≤ 10 4 1 \le t \le 10^4 1≤t≤104)。接下来是测试用例的描述。
每个测试用例的第一行包含一个整数 n n n ( 2 ≤ n ≤ 2 ⋅ 10 5 2 \le n \le 2 \cdot 10^5 2≤n≤2⋅105) ------ T T T 中顶点的数量。
接下来是 n − 1 n - 1 n−1 行,第 i i i 行包含两个整数 u i u_i ui 和 v i v_i vi ( 1 ≤ u i < v i ≤ n 1 \le u_i < v_i \le n 1≤ui<vi≤n) ------ 第 i i i 条边连接的两个顶点。
保证给定的边构成一棵树。
保证所有测试用例的 n n n 的总和不超过 2 ⋅ 10 5 2 \cdot 10^5 2⋅105。
输出
对于每个测试用例,输出一个整数 ------ 可以从 T T T 构建出的不同"征服树"的数量,结果对 998 244 353 998\,244\,353 998244353 取模。
Solutions
Approach 1
不变量。
思路基本与题解 Good Bye 2025 Editorial - Codeforces 无差。
大致就是,发现在将任意初始时的白色节点与父节点的边断开后,整片森林中的每一棵树都是一个不变量。视为无根树下,即不可能再通过连接断开来影响树的形态。
于是只需要把所有其他的树拼到 1 所在的树上就好。
Code
cpp
#include<bits/stdc++.h>
using namespace std;
std::mt19937 rng(std::random_device{}());
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 998244353;
const double ept = 1e-9;
ll add(ll x, const ll&y) { x += y; if(x >= mod) { x -= mod; } return x; }
ll sub(ll x, const ll&y) { x -= y; if(x < 0) { x += mod; } return x; }
ll mul(ll x, const ll&y) { x = x * y; if(x >= mod) { x %= mod; } return x; }
#ifndef ONLINE_JUDGE
#define DEBUG 1
#define fastio
#define coutd cout
#define db(i) cout << #i << ": " << i << endl;
#define dbl(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__);
#define dbi(vec) { cout << #vec << ": "; for(auto &v: vec) { cout << v << ' '; } cout << endl; }
#define dbv(vec, a, b) { cout << #vec << ": "; for(int i=a; i!=b+sig(b-a); i+=sig(b-a)) { cout << vec[i] << ' '; } cout << endl; }
#else
#define DEBUG 0
#define fastio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define coutd cerr
#define db(...)
#define dbl(fmt, ...)
#define dbi(vec)
#define dbv(vec, a, b)
#endif
ll fac[200200];
int n;
int sum[200200];
vector<int> to[200200];
vector<ll> p;
ll ksm(ll bs, int x) {
ll ans = 1;
while(x) {
if(x & 1) ans = ans * bs % mod;
bs = bs * bs % mod;
x >>= 1;
}
return ans;
}
void dfs(int u, int f) {
for(auto &v: to[u]) {
if(v == f) continue;
dfs(v, u);
}
for(auto &v: to[u]) {
if(v == f) continue;
if(sum[v] & 1) sum[u] += sum[v];
}
if(!(sum[u]&1) && u != 1) {
p.push_back(sum[u]);
}
}
void solve(int T) {
cin >> n;
p.clear();
for(int i=1; i<=n; i++) {
to[i].clear();
sum[i] = 1;
}
int u, v;
for(int i=1; i<n; i++) {
cin >> u >> v;
to[u].push_back(v);
to[v].push_back(u);
}
dfs(1, 1);
ll pre = sum[1] % mod;
for(auto &u: p) pre = (pre * u) % mod * u % mod;
ll ans = 0;
for(auto &u: p) {
ll now = pre * ksm(u, mod-2) % mod * fac[p.size()-1] % mod;
ans = (ans + now) % mod;
}
cout << (ans == 0 ? 1 : ans) << endl;
}
void init() {
fac[0] = 1;
for(int i=1; i<=2e5; i++) fac[i] = (fac[i-1] * i) % mod;
}
signed main() {
//freopen("1.in", "r", stdin);
//freopen("1.out", "w", stdout);
//cout.flags(ios::fixed); cout.precision(8);
fastio
init();
int T_=1;
std::cin >> T_;
for(int _T=1; _T<=T_; _T++) { solve(_T); }
return 0;
}