新年快乐!
by もや造
题意
有(n+1)个点,对于每个点(i(i≤n))都有一条连向(i+1)的边,形成一条链,并在其中加入(m)条返祖边
现在从1号节点出发,每次等概率的前往到一个相邻的节点,求走到第(n+1)个点的期望步数
(n,m≤10^6)
分析
设(E_{x→y})表示从(x)点走到(y)点的期望步数,(k_i)表示第(i)个点的返祖边条数
有转移:
根据期望的线性性质,有(E_{x→y} =sumlimits_{i=x}^{y-1}E_{i→i+1}),代回原式:
维护一下前缀和即可,(sumlimits_{i=x}^{y-1}E_{i→i+1})既为所求答案
时间复杂度(O(n+m))
(code)
//xcxc82 2021/2/9/20:50
#include<bits/stdc++.h>
#define mo 998244353
using namespace std;
const int MAXN = 1000010;
inline int read(){
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;return ~(X-1);
}
struct edge{
int to,from,next;
}e[MAXN<<2];
int head[MAXN<<2],cnt;
void add(int u,int v){
e[++cnt].next = head[u];
e[cnt].from = u;
e[cnt].to = v;
head[u] = cnt;
}
int id,n,m,out[MAXN],sum[MAXN],f[MAXN];
int main(){
id = read(),n =read(),m = read();
for(int i=1;i<=m;i++){
int u = read(),v =read();
add(u,v);
out[u]++;
}
for(int u=1;u<=n;u++){
f[u] = 1+out[u];
for(int i=head[u];i;i=e[i].next){
int v = e[i].to;
f[u] = (f[u]+(sum[u-1]-sum[v-1]+mo)%mo)%mo;
}
sum[u] = (sum[u-1]+f[u])%mo;
}
printf("%d",sum[n]);
return 0;
}