Easy to think of violence DP: For each first into \ (K \) obtaining \ (\ max_ {i \ in S} | i-w_i | \ le k \) program number, the last difference
The question then converted to a weight of each leaf has a value interval, then we can note that the value of the weight of each point into \ (<W is, W is =,> W is \) (considered \ (0,1, 2 \) ) three types of treatment and then the DP \ (F [U] [0/1/2] \)
Then you will soon find that do not, because when some selected set of leaf, root weights may be less than \ (W is \) may be larger than \ (W is \) , directly \ (2 ^ m-1 \ ) subtracting \ (f [u] [0 ] + f [u] [2] \) can not get the correct result
So we try to consider how the \ (<\ W) and \ (> W \) remove one of these two conditions
Consider a weight of \ (W \) a chain leaf to the root
Easy to find root weights will be changed, if and when this point there is only one strand will be changed
On this chain there is provided a depth point odd \ (U \) (even-numbered Similarly), after considering all side chain are deleted (U \) \ where the communication block
Readily available in the original tree \ (U \) is changed weights, if and only if after Erase on \ (U \) communication block is located , let \ (U \) weights greater than \ (W is \ )
Particularly, if the \ (U \) is a leaf then the \ (U \) weights are changed if and only if \ (U \) in the selected set and \ (k> 0 \)
So that we achieved in the \ (<W \) and \ (> W \) remove one of these two conditions
We have a DP: \ (f [U] \) represents \ (u \) leaves in the sub-tree node how many subsets let \ (u \) weights greater than \ (W \)
If \ (U \) (depth of odd \ (CNT_U \) of \ (U \) leaves the number of sub-tree):
\[f[u]=2^{cnt_u}-\prod_{v\in son[u]}(2^{cnt_v}-f[v])\]
otherwise:
\[f[u]=\prod_{v\in son[u]}f[v]\]
The result of all DP block communication with \ (2 ^ {cnt} \ ) after subtracting take up, the root node is the weight not changed the number of programs
For each \ (K \) complexity is performed DP \ (O (n ^ 2) \)
Consider how to optimize. We note that this transfer and DP (k \) \ unrelated, only the initial value (leaves) and \ (k \) related
If a point \ (U \) depth where communication roots in the original tree is odd, then the point \ (U \) is the initial value should be:
\[f[u]=[u>W]+[u+k>W]\]
Note that when \ (k \) continues to add a time, \ ([U + k> W] \) changes only once
Thus ascending enumeration \ (K \) after moving to DP
Note Because of \ (f [u] \) may be \ (0 \) , when it is not the updated value DP up \ (f [fa [u] ] \) is directly divided by \ (f [u] \) , the need to maintain a variable each point represents the value of the sub node DP how many \ (0 \) , the other variable represents the child node is \ (0 \) product of value DP
\(O(n\log^2n)\)
Code
#include <bits/stdc++.h>
#define p2 p << 1
#define p3 p << 1 | 1
template <class T>
inline void read(T &res)
{
res = 0; bool bo = 0; char c;
while (((c = getchar()) < '0' || c > '9') && c != '-');
if (c == '-') bo = 1; else res = c - 48;
while ((c = getchar()) >= '0' && c <= '9')
res = (res << 3) + (res << 1) + (c - 48);
if (bo) res = ~res + 1;
}
template <class T>
inline T Min(const T &a, const T &b) {return a < b ? a : b;}
template <class T>
inline T Max(const T &a, const T &b) {return a > b ? a : b;}
const int N = 2e5 + 5, M = N << 1, L = M << 1, rqy = 998244353;
int n, l, r, dep[N], ecnt, nxt[M], adj[N], go[M], val[N], ans[N], f[N], cnt[N],
fa[N], sze[N], son[N], top[N], pos[N], idx[N], bot[N], QAQ, pw[N], re[N], c0[N],
rea = 1, cnt0;
bool lea[N], bel[N];
int qpow(int a, int b)
{
int res = 1;
while (b)
{
if (b & 1) res = 1ll * res * a % rqy;
a = 1ll * a * a % rqy;
b >>= 1;
}
return res;
}
struct modi
{
int a, b;
friend inline modi operator * (modi x, modi y)
{
return (modi) {(int) (1ll * x.a * y.a % rqy),
(int) ((1ll * x.a * y.b + x.b) % rqy)};
}
friend inline int operator * (modi x, int y)
{
return (1ll * x.a * y + x.b) % rqy;
}
} g[N], gp[L];
void add_edge(int u, int v)
{
nxt[++ecnt] = adj[u]; adj[u] = ecnt; go[ecnt] = v;
nxt[++ecnt] = adj[v]; adj[v] = ecnt; go[ecnt] = u;
}
void dfs(int u, int fu)
{
dep[u] = dep[fu] + 1;
val[u] = dep[u] & 1 ? 1 : n;
bool is = 1;
for (int e = adj[u], v; e; e = nxt[e])
if ((v = go[e]) != fu)
{
dfs(v, u); is = 0;
if (dep[u] & 1) val[u] = Max(val[u], val[v]);
else val[u] = Min(val[u], val[v]);
}
if (is) lea[val[u] = u] = 1, ans[0] = (ans[0] + ans[0]) % rqy;
}
void dfs1(int u, int fu, bool op)
{
fa[u] = fu; sze[u] = 1; bel[u] = op; cnt[u] = lea[u];
for (int e = adj[u], v; e; e = nxt[e])
if ((v = go[e]) != fu && val[v] != val[1])
{
dfs1(v, u, op);
sze[u] += sze[v]; cnt[u] += cnt[v];
if (sze[v] > sze[son[u]]) son[u] = v;
}
f[u] = (op ? val[u] > val[1] : val[u] < val[1]) ? pw[cnt[u]] : 0;
g[u].a = re[u] = 1;
if ((dep[u] & 1) ^ op)
{
for (int e = adj[u], v; e; e = nxt[e])
if ((v = go[e]) != fu && val[v] != val[1] && v != son[u])
{
g[u].a = 1ll * g[u].a * f[v] % rqy;
if (f[v]) re[u] = 1ll * re[u] * f[v] % rqy; else c0[u]++;
}
}
else
{
for (int e = adj[u], v; e; e = nxt[e])
if ((v = go[e]) != fu && val[v] != val[1] && v != son[u])
{
int tmp = (pw[cnt[v]] - f[v] + rqy) % rqy;
g[u].a = 1ll * g[u].a * tmp % rqy;
if (tmp) re[u] = 1ll * re[u] * tmp % rqy; else c0[u]++;
}
g[u].b = (pw[cnt[u]] - 1ll * g[u].a * pw[cnt[son[u]]] % rqy + rqy) % rqy;
}
bot[u] = son[u] ? bot[son[u]] : u;
}
void dfs2(int u, int fu)
{
if (son[u])
{
top[son[u]] = top[u];
idx[pos[son[u]] = ++QAQ] = son[u];
dfs2(son[u], u);
}
for (int e = adj[u], v; e; e = nxt[e])
if ((v = go[e]) != fu && v != son[u] && val[v] != val[1])
top[v] = v, idx[pos[v] = ++QAQ] = v, dfs2(v, u);
}
void build(int l, int r, int p)
{
if (l == r) return (void) (gp[p] = g[idx[l]]);
int mid = l + r >> 1;
build(l, mid, p2); build(mid + 1, r, p3);
gp[p] = gp[p2] * gp[p3];
}
void change(int l, int r, int pos, modi v, int p)
{
if (l == r) return (void) (gp[p] = v);
int mid = l + r >> 1;
if (pos <= mid) change(l, mid, pos, v, p2);
else change(mid + 1, r, pos, v, p3);
gp[p] = gp[p2] * gp[p3];
}
modi ask(int l, int r, int s, int e, int p)
{
if (e < l || s > r) return (modi) {1, 0};
if (s <= l && r <= e) return gp[p];
int mid = l + r >> 1;
return ask(l, mid, s, e, p2) * ask(mid + 1, r, s, e, p3);
}
void modify(int u, int x)
{
bool fi = 1; int of;
while (1)
{
int v = top[u], w = fa[v], rf = f[v], nf;
if (fi) fi = 0, f[u] = x; nf = f[v];
if (v != bot[u]) nf = f[v] =
ask(1, n, pos[v], pos[bot[u]] - 1, 1) * f[bot[u]] % rqy;
if (!w) {of = rf; u = v; break;}
if ((dep[v] & 1) ^ bel[v]) rf = (pw[cnt[v]] - rf + rqy) % rqy,
nf = (pw[cnt[v]] - nf + rqy) % rqy;
if (!rf) c0[w]--; else re[w] = 1ll * re[w] * qpow(rf, rqy - 2) % rqy;
if (!nf) c0[w]++; else re[w] = 1ll * re[w] * nf % rqy;
g[w].a = c0[w] ? 0 : re[w];
g[w].b = (dep[w] & 1) ^ bel[w] ? 0 : (pw[cnt[w]] -
1ll * g[w].a * pw[cnt[son[w]]] % rqy + rqy) % rqy;
change(1, n, pos[w], g[w], 1);
u = w;
}
if (of == pw[cnt[u]]) cnt0--; else rea = 1ll * rea *
qpow(pw[cnt[u]] - of + rqy, rqy - 2) % rqy;
if (f[u] == pw[cnt[u]]) cnt0++;
else rea = 1ll * rea * (pw[cnt[u]] - f[u] + rqy) % rqy;
}
int main()
{
int x, y;
read(n); read(l); read(r);
for (int i = 1; i < n; i++)
read(x), read(y), add_edge(x, y);
ans[0] = pw[0] = ans[n] = 1; dfs(1, 0);
for (int i = 1; i <= n; i++) pw[i] = (pw[i - 1] + pw[i - 1]) % rqy;
rea = 499122177ll * ans[0] % rqy;
for (int u = 1; u <= n; u++)
{
if (val[u] != val[1] || u == val[1]) continue;
dfs1(u, 0, dep[u] & 1);
if (!cnt[u] || lea[u]) continue;
idx[pos[u] = ++QAQ] = top[u] = u;
dfs2(u, 0);
}
build(1, n, 1);
for (int i = 1; i < n; i++)
{
if (i > 1 && val[1] >= i && lea[val[1] - i + 1] && bel[val[1] - i + 1])
modify(val[1] - i + 1, 1);
if (i > 1 && val[1] <= n - i + 1 && lea[val[1] + i - 1]
&& !bel[val[1] + i - 1]) modify(val[1] + i - 1, 1);
ans[i] = cnt0 ? 0 : rea;
}
for (int i = l; i <= r; i++) printf("%d ", (ans[i - 1] - ans[i] + rqy) % rqy);
return puts(""), 0;
}