题意
题解
设
D
i
D_i
Di 为
i
→
N
+
1
i\rightarrow N+1
i→N+1 步数的数学期望,
d
i
d_i
di 为与
i
i
i 相连的返祖边的出度。考虑前进一步的情况,则有
D
i
=
1
+
1
d
i
+
1
D
i
+
1
+
1
d
i
+
1
∑
e
(
i
,
j
)
∈
G
,
j
≤
i
D
j
D_i=1+\frac{1}{d_i+1}D_{i+1}+\frac{1}{d_i+1}\sum\limits_{e(i,j)\in G,j\leq i}D_j
Di=1+di+11Di+1+di+11e(i,j)∈G,j≤i∑Dj 式子右侧同时出现了标号大于
i
i
i 与小于等于
i
i
i 的项,不易递推求解。将
D
i
+
1
D_{i+1}
Di+1 单独归到等式一侧,则满足其递推式中出现的项标号都小于其本身。那么不断迭代,将
D
i
+
1
D_{i+1}
Di+1 表示为
D
0
D_{0}
D0 与常数的线性组合,最后求解线性同余方程即可。但运算中不保证逆元一定存在,考虑避免除法。
重新定义
D
D
D,设
D
i
,
i
+
1
D_{i,i+1}
Di,i+1 为
i
→
i
+
1
i\rightarrow i+1
i→i+1 步数的数学期望,则递推式为
D
i
,
i
+
1
=
1
+
1
d
i
+
1
∑
e
(
i
,
j
)
∈
G
,
j
≤
i
D
j
,
i
+
1
D_{i,i+1}=1+\frac{1}{d_i+1}\sum\limits_{e(i,j)\in G,j\leq i}D_{j,i+1}
Di,i+1=1+di+11e(i,j)∈G,j≤i∑Dj,i+1 对于
j
,
j
≤
i
j,j\leq i
j,j≤i,有
i
i
i 为
j
→
i
+
1
j\rightarrow i+1
j→i+1 的必经点,根据数学期望的线性性质,有
D
j
,
i
+
1
=
D
j
,
i
+
D
i
,
i
+
1
D_{j,i+1}=D_{j,i}+D_{i,i+1}
Dj,i+1=Dj,i+Di,i+1 代入上式变形得到
D
i
,
i
+
1
=
d
i
+
1
+
∑
e
(
i
,
j
)
∈
G
,
j
≤
i
∑
k
∈
[
j
,
i
)
D
k
D_{i,i+1}=d_i+1+\sum\limits_{e(i,j)\in G,j\leq i}\sum\limits_{k\in [j,i)} D_{k}
Di,i+1=di+1+e(i,j)∈G,j≤i∑k∈[j,i)∑Dk 递推求解,同时维护前缀和,总时间复杂度
O
(
N
+
M
)
O(N+M)
O(N+M)。
#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = l, _ = r; i < _; ++i)
const int maxn = 1000005, mod = 998244353;
int Id, N, M, D[maxn], sum[maxn];
vector<int> G[maxn];
int rd()
{
int x = 0;
char c = 0;
for (; !isdigit(c); c = getchar())
;
for (; isdigit(c); c = getchar())
x = (x << 1) + (x << 3) + c - '0';
return x;
}
int main()
{
Id = rd(), N = rd(), M = rd();
rep(i, 0, M)
{
int u, v;
u = rd(), v = rd();
--u, --v;
G[u].push_back(v);
}
sum[0] = 0;
rep(u, 0, N)
{
D[u] = G[u].size() + 1;
for (auto &v : G[u])
D[u] = (D[u] + (sum[u] - sum[v] + mod) % mod) % mod;
sum[u + 1] = (sum[u] + D[u]) % mod;
}
cout << sum[N] << '\n';
return 0;
}