本文搬运自本人初中博客园博客,若图片加载不出来,可到原文查看:https://www.cnblogs.com/zhangtingxi/p/15552685.html
明显是道期望dp,设 f i = E i → i + 1 f_i=E_{i\rightarrow i+1} f i = E i → i + 1 。表示从第 i i i 层到第 i + 1 i+1 i + 1 层的期望步数。
所以 E x → y = ∑ i = x y f i E_{x\rightarrow y}=\sum_{i=x}^yfi E x → y = ∑ i = x y f i ,即从第 x x x 层走到第 y y y 层的总期望步数。
现在推 f x f_x f x , 设 d x d_x d x 为 x x x 的返祖边条数,g x g_x g x 为 x x x 返祖到的点的集合,则:
f x = 1 d x + 1 × 1 + 1 d x + 1 × ∑ y ∈ g x ( E x → y + 1 ) f_x=\frac{1}{d_x+1}\times 1+\frac{1}{d_x+1}\times\sum_{y\in g_x}(E_{x\rightarrow y}+1)
f x = d x + 1 1 × 1 + d x + 1 1 × y ∈ g x ∑ ( E x → y + 1 )
后面那坨拆开:
f x = 1 d x + 1 × 1 + d x d x + 1 + 1 d x + 1 × ∑ y ∈ g x E x → y f_x=\frac{1}{d_x+1}\times 1+\frac{d_x}{d_x+1}+\frac{1}{d_x+1}\times\sum_{y\in g_x}E_{x\rightarrow y}
f x = d x + 1 1 × 1 + d x + 1 d x + d x + 1 1 × y ∈ g x ∑ E x → y
把前两坨合并:
f x = 1 + 1 d x + 1 × ∑ y ∈ g x E x → y f_x=1+\frac{1}{d_x+1}\times\sum_{y\in g_x}E_{x\rightarrow y}
f x = 1 + d x + 1 1 × y ∈ g x ∑ E x → y
按照开始的公式我们可以把后面的替换掉:
f x = 1 + 1 d x + 1 × ∑ y ∈ g x ∑ i = x y f i f_x=1+\frac{1}{d_x+1}\times\sum_{y\in g_x}\sum_{i=x}^yfi
f x = 1 + d x + 1 1 × y ∈ g x ∑ i = x ∑ y f i
最后那个 ∑ i = x y f i \sum_{i=x}^yfi ∑ i = x y f i 明显可以用前缀和维护,则:
f x = 1 + 1 d x + 1 × ∑ y ∈ g x ( S x − S y − 1 ) f_x=1+\frac{1}{d_x+1}\times\sum_{y\in g_x}(S_x-S_{y-1})
f x = 1 + d x + 1 1 × y ∈ g x ∑ ( S x − S y − 1 )
由于 S x S_x S x 未求出,我们可以把它拆开:
f x = 1 + 1 d x + 1 × ∑ y ∈ g x ( f x + S x − 1 − S y − 1 ) f_x=1+\frac{1}{d_x+1}\times\sum_{y\in g_x}(f_x+S_{x-1}-S_{y-1})
f x = 1 + d x + 1 1 × y ∈ g x ∑ ( f x + S x − 1 − S y − 1 )
拆开:
f x = 1 + 1 d x + 1 × ∑ y ∈ g x ( S x − 1 − S y − 1 ) + 1 d x + 1 × d x × f x f_x=1+\frac{1}{d_x+1}\times\sum_{y\in g_x}(S_{x-1}-S_{y-1})+\frac{1}{d_x+1}\times d_x \times f_x
f x = 1 + d x + 1 1 × y ∈ g x ∑ ( S x − 1 − S y − 1 ) + d x + 1 1 × d x × f x
两边同乘 d x + 1 d_x+1 d x + 1 :
f x × ( d x + 1 ) = d x + 1 + ∑ y ∈ g x ( S x − 1 − S y − 1 ) + d x × f x f_x\times(d_x+1)=d_x+1+\sum_{y\in g_x}(S_{x-1}-S_{y-1})+d_x\times f_x
f x × ( d x + 1 ) = d x + 1 + y ∈ g x ∑ ( S x − 1 − S y − 1 ) + d x × f x
最后面的 d x × f x d_x\times f_x d x × f x 移到左边:
f x × ( d x + 1 ) − d x × f x = d x + 1 + ∑ y ∈ g x ( S x − 1 − S y − 1 ) f_x\times(d_x+1)-d_x\times f_x=d_x+1+\sum_{y\in g_x}(S_{x-1}-S_{y-1})
f x × ( d x + 1 ) − d x × f x = d x + 1 + y ∈ g x ∑ ( S x − 1 − S y − 1 )
化简一下:
f x = d x + 1 + ∑ y ∈ g x ( S x − 1 − S y − 1 ) f_x=d_x+1+\sum_{y\in g_x}(S_{x-1}-S_{y-1})
f x = d x + 1 + y ∈ g x ∑ ( S x − 1 − S y − 1 )
最终转移方程就求出来了
上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 // Problem: P6835 [Cnoi2020]线形生物 // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P6835 // Memory Limit: 128 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; #define int long long inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+ (x<<3)+(ch^48);ch=getchar();}return x*f;} #define mo 998244353 #define N 1000010 struct node { int x, y, n; }d[2*N]; int n, m, i, j, k; int f[N], rd[N], s[N], h[N]; int u, v, w, x, y; void cun(int x, int y) { ++k; d[k].x=x; d[k].y=y; d[k].n=h[x]; h[x]=k; rd[x]++; } signed main() { // freopen("tiaoshi.in","r",stdin); // freopen("tiaoshi.out","w",stdout); read(); n=read(); m=read(); for(i=1; i<=m; ++i) { v=read(); u=read(); cun(v, u); } for(x=1; x<=n; ++x) { f[x]=rd[x]+1; for(j=h[x]; j; j=d[j].n) { y=d[j].y; f[x]+=(s[x-1]-s[y-1]); } f[x]=(f[x]%mo+mo)%mo; s[x]=(s[x-1]+f[x])%mo; } printf("%lld", s[n]); return 0; }