zoukankan      html  css  js  c++  java
  • 【洛谷P6835】线形生物

    题目

    题目链接:https://www.luogu.com.cn/problem/P6835
    线形生物要从 \(1\) 号台阶走到 \(n+1\) 号台阶。

    最开始,\(1,2,3,\ldots,n\) 号台阶都有一条连向下一台阶的有向边 \(i\rightarrow i+1\)

    之后 Cirno 加入了 \(m\)返祖边 \(u_i \rightarrow v_i (u_i \ge v_i)\),它们构成了一个返祖图

    线形生物每步会 等概率地 选取当前台阶的一条出边并走向对应的台阶。

    当走到 \(n+1\) 号台阶时,线形生物就会停止行走。

    同时,Cirno 会统计线性生物总共走的步数,记作 \(\delta\)

    Cirno 想知道 \(E(\delta)\)(即 \(\delta\)数学期望)对 \(998244353\) 取模后的结果。

    思路

    \(f[i]\) 表示从 \(i\) 走到 \(i+1\) 的期望步数,\(g[i]=sum^{i}_{j=1}f[j]\)。那么答案即为 \(g[n]\)
    \(c[i]\) 表示点 \(i\) 往回走的路径数量。那么有

    \[f[i]=\frac{\sum^{c[i]}_{j=1}(g[i]-g[to[j]-1]+1)+1}{c[i]+1} \]

    \(g[i]\) 拆成 \(g[i-1]+f[i]\),解方程得

    \[f[i]=c[i]g[i-1]+c[i]+1-\sum^{c[i]}_{j=1}g[to[j]] \]

    时间复杂度 \(O(n)\)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=1000010,MOD=998244353;
    int n,m,WYCAKIOI,tot,head[N],cnt[N];
    ll f[N],g[N];
    
    ll fpow(ll x,int k)
    {
    	ll ans=1;
    	for (;k;k>>=1,x=x*x%MOD)
    		if (k&1) ans=ans*x%MOD;
    	return ans;
    }
    
    struct edge
    {
    	int next,to;
    }e[N];
    
    void add(int from,int to)
    {
    	e[++tot].to=to;
    	e[tot].next=head[from];
    	head[from]=tot;
    }
    
    int main()
    {
    	memset(head,-1,sizeof(head));
    	scanf("%d%d%d",&WYCAKIOI,&n,&m);
    	for (int i=1,x,y;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		add(x,y); cnt[x]++;
    	}
    	for (int i=1;i<=n;i++)
    	{
    		f[i]=(cnt[i]+1LL+cnt[i]*g[i-1])%MOD;
    		for (int j=head[i];~j;j=e[j].next)
    			f[i]=(f[i]-g[e[j].to-1]+MOD)%MOD;
    		g[i]=(g[i-1]+f[i])%MOD;
    	}
    	printf("%lld",g[n]);
    	return 0;
    }
    
  • 相关阅读:
    PHP中get请求中参数的key不能是para
    js对数组中的数字排序
    js 数组不重复添加元素
    Controllers
    Views
    Models
    Requirements
    Pull Requests
    Upgrade Guide
    Overview & Change Log
  • 原文地址:https://www.cnblogs.com/stoorz/p/13697611.html
Copyright © 2011-2022 走看看