题目需要求 (u,v) 路径长度总和,这是不好解决的,所以考虑转化为期望,最后再乘 (n−1)!。
根据期望的线性性,就可以设 fi 表示 i 的期望深度,那么答案就为 fu+fv−2flca(u,v)。
前两者是好做的,因为根据定义显然有转移式 fi=ai+1i−1i−1∑j=1fj。
但是 lca 这件事就很麻烦,因为树的形态不同 lca 也不相同。
实际上 lca(u,v) 的期望深度只和 u 有关。
考虑钦定 u<v,可以让 v 不断往上跳直到发现 v 的父亲编号 ≤u。
下一步显然 v 跳到 1≤t≤u 中任意一个点 t 的概率是均等的。
而且观察到前半部分跳跃和后半部分跳跃是独立的,因此 lca 的期望深度只和 u 有关,并且 lca(u,v)=lca(u,u+1)。
设 gu 表示固定 u 之后,lca(u,v) 的期望深度。
要么 u 作为 lca,要么再往前的点作为 lca。
因此有转移式 gu=fu+u−1∑i=1giu。
记得乘阶乘。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 15, mod = 998244353;
int qmi(int a, int k) {
int res = 1;
while (k) {
if (k & 1) res = res * 1ll * a % mod;
a = a * 1ll * a % mod;
k >>= 1;
}
return res;
}
int inv(int x) { return qmi(x, mod - 2); }
int n, m, a[N], f[N], g[N];
int main() {
scanf("%d%d", &n, &m);
for (int i = 2; i <= n; i++) scanf("%d", &a[i]);
long long sumf = 0, sumg = 0, mul = 1;
for (int i = 2; i < n; i++) (mul *= i) %= mod;
for (int i = 2; i <= n; i++) f[i] = ( a[i] + (sumf * 1ll * inv(i - 1) % mod) ) % mod, (sumf += f[i]) %= mod;
for (int i = 2; i <= n; i++) g[i] = (f[i] + sumg) * 1ll * inv(i) % mod, (sumg += g[i]) %= mod;
while (m--) {
int u, v; scanf("%d%d", &u, &v);
if (u > v) swap(u, v);
if (u ^ v) printf("%d\n", ( (f[u] + f[v] - 2 * g[u]) % mod + mod ) * 1ll * mul % mod);
else puts("0");
}
return 0;
}