洛谷 P6835 [Cnoi2020] 线形生物 题解

Announcement

  • Programmed on 2024/2/25
  • Written on 2024/2/25

题目来源

Description

给定 n + 1 n+1 n+1 个节点,其中对于每个节点 i ≤ n i\le n in,都有一条边 i → i + 1 i\to i+1 ii+1,同时给定 m m m 条返祖边 u → v u\to v uv(其中 u ≥ v u\ge v uv)。

求从 1 1 1 号节点出发,每次等概率地沿着当前所在节点的出边去往下一个节点,最终到达 n + 1 n+1 n+1 号节点的期望步数。

  • 1 ≤ n , m ≤ 1 0 6 1\le n,m\le10^6 1n,m106

Solution

对于在图上随机游走的问题,有一个基于期望的线性性质的通用的技巧。

对于本题,若设 E x → y E_{x\to y} Exy 表示从 x x x y y y 的期望步数,则 E x → y = ∑ i = x y − 1 E x → x + 1 E_{x\to y}=\sum\limits_{i=x}^{y-1}E_{x\to x+1} Exy=i=xy1Exx+1

那么,只需求出所有 i ∈ [ 1 , n ] ∩ Z i\in[1,n]\cap\Z i[1,n]Z E i → i + 1 E_{i\to i+1} Eii+1,答案即为 ∑ i = 1 n E i → i + 1 \sum\limits_{i=1}^nE_{i\to i+1} i=1nEii+1

为何是从 1 1 1 开始求和呢?因为可能存在自环, E 1 → 1 E_{1\to1} E11 并非恒等于 0 0 0

考虑如何计算 E x → x + 1 E_{x\to x+1} Exx+1

若设节点 x x x d e g x deg_x degx 个返祖出边, E E E 为返祖边的集合, f x = E x → x + 1 f_x=E_{x\to x+1} fx=Exx+1 s u m x = ∑ i = 1 x f x sum_x=\sum\limits_{i=1}^xf_x sumx=i=1xfx。则根据期望的计算公式有:
f x = 1 d e g x + 1 ⋅ 1 + 1 d e g x + 1 ⋅ ∑ ( x , y ) ∈ E ( E y → x + 1 + 1 ) = 1 d e g x + 1 + 1 d e g x + 1 ∑ ( x , y ) ∈ E ( s u m x − s u m y − 1 ) + d e g x d e g x + 1 = 1 + d e g x d e g x + 1 f x + 1 d e g x + 1 ∑ ( x , y ) ∈ E ( s u m x − 1 − s u m y − 1 ) \begin{aligned} f_x&=\frac1{deg_x+1}\cdot1+\frac1{deg_x+1}\cdot\sum\limits_{(x,y)\in E}(E_{y\to x+1}+1)\\ &=\frac1{deg_x+1}+\frac1{deg_x+1}\sum\limits_{(x,y)\in E}(sum_x-sum_{y-1})+\frac{deg_x}{deg_x+1}\\ &=1+\frac{deg_x}{deg_x+1}f_x+\frac1{deg_x+1}\sum\limits_{(x,y)\in E}(sum_{x-1}-sum_{y-1})\\ \end{aligned} fx=degx+111+degx+11(x,y)E(Eyx+1+1)=degx+11+degx+11(x,y)E(sumxsumy1)+degx+1degx=1+degx+1degxfx+degx+11(x,y)E(sumx1sumy1)
f x f_x fx 合并至等式左侧有:
1 d e g x + 1 f x = 1 + 1 d e g x + 1 ∑ ( x , y ) ∈ E ( s u m x − 1 − s u m y − 1 ) f x = d e g x + 1 + ∑ ( x , y ) ∈ E ( s u m x − 1 − s u m y − 1 ) \begin{aligned} \frac1{deg_x+1}f_x&=1+\frac1{deg_x+1}\sum\limits_{(x,y)\in E}(sum_{x-1}-sum_{y-1})\\ f_x&=deg_x+1+\sum\limits_{(x,y)\in E}(sum_{x-1}-sum_{y-1}) \end{aligned} degx+11fxfx=1+degx+11(x,y)E(sumx1sumy1)=degx+1+(x,y)E(sumx1sumy1)
从小到大依次计算 f x f_x fx 即可,复杂度 O ( n + m ) O(n+m) O(n+m)

Conclusion

  • 对于在图上随机游走的问题,可将期望拆分成每一步的期望之和。

Code

#include <bits/stdc++.h>
using namespace std;
const int p=998244353;
int id,n,m,head[1000005],ver[1000005],nxt[1000005],tot,deg[1000005],f[1000005],sum[1000005]; // f[i] i->i+1的期望步数
void add(int u,int v){
	ver[++tot]=v,deg[u]++;
	nxt[tot]=head[u],head[u]=tot;
}
int main(){
	scanf("%d%d%d",&id,&n,&m);
	for (int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),add(u,v);
	for (int i=1;i<=n;i++){
		f[i]=deg[i]+1;
		for (int j=head[i];j;j=nxt[j]){
			int u=ver[j];
			f[i]=((f[i]+sum[i-1]-sum[u-1])%p+p)%p;
		}
		sum[i]=(sum[i-1]+f[i])%p;
	}
	printf("%d\n",sum[n]);
	return 0;
}
  • 27
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值