zoukankan      html  css  js  c++  java
  • 洛谷 P6154 游走

    洛谷 P6154 游走

    洛谷传送门

    题目背景

    zbw 在 B 城游走。

    题目描述

    B 城可以看作一个有 nn 个点 mm 条边的有向无环图可能存在重边

    zbw 在 B 城随机游走,他会随机选择一条路径,选择所有路径的概率相等。路径的起点和终点可以相同。

    定义一条路径的长度为经过的边数,你需要求出 zbw 走的路径长度的期望,答案对 998244353998244353 取模。

    输入格式

    第一行两个整数 n,mn,m

    接下来 mm 行,每行两个整数 x,yx,y,表示存在一条从 xx 到 yy 的有向边。

    输出格式

    一行一个整数,表示答案对 998244353998244353 取模后的值。


    题解:

    暴力思路:

    从每个点开始全图遍历,累加出所有路径条数和路径长度和,两者相除求逆元即是答案。

    开Longlong。

    目标40pts,实测 pts。

    代码:

    #include<cstdio>
    #define int long long
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=7*1e5+10;
    const int tt=5*1e6;
    const int mod=998244353;
    int n,m,cnt,tmp;
    int tot,to[maxm],nxt[maxm],head[maxn];
    int inv[tt];
    void add(int x,int y)
    {
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    void dfs(int x,int dep)
    {
        cnt++;
        tmp+=dep;
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            dfs(y,dep+1);
        }
    }
    signed main()
    {
        scanf("%lld%lld",&n,&m);
        inv[1]=1;
        for(int i=2;i<=tt;i++)
            inv[i]=((mod-mod/i)*inv[mod%i])%mod;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%lld%lld",&x,&y);
            add(x,y);
        }
        for(int i=1;i<=n;i++)
            dfs(i,0);
        int ans=(tmp*inv[cnt])%mod;
        printf("%lld
    ",ans);
        return 0;
    }
    

    正解记忆化?本来以为是什么期望DP+拓排之类的小神题(当然对于学弟来讲是水题)。结果正解就是暴搜+记忆化优化。

    怀疑人生。

    逆元没有必要拿线性求逆元,因为998244353是质数,所以逆元直接就是(a^{p-2}),快速幂即可。

    代码:

    #include<cstdio>
    #define int long long
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=7*1e5+10;
    const int tt=5*1e6;
    const int mod=998244353;
    int n,m,cnt,tmp,ans;
    int tot,to[maxm],nxt[maxm],head[maxn];
    int f[maxn],g[maxn];
    //f[i]表示以i为起点的路径条数,g[i]表示以i为起点的路径总长
    void add(int x,int y)
    {
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    void dfs(int x)
    {
        if(f[x])
            return;
        f[x]=1;
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            dfs(y);
            f[x]=(f[x]+f[y])%mod;
            g[x]=(g[x]+f[y]+g[y])%mod;
        }
    }
    int qpow(int a,int b)
    {
        int ret=1;
        while(b)
        {
            if(b&1)
                ret=(ret*a)%mod;
            b>>=1;
            a=(a*a)%mod;
        }
        return ret%mod;
    }
    signed main()
    {
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%lld%lld",&x,&y);
            add(x,y);
        }
        for(int i=1;i<=n;i++)
            if(!f[i])
                dfs(i);
        for(int i=1;i<=n;i++)
        {
            cnt=(cnt+f[i])%mod;
            tmp=(tmp+g[i])%mod;
        }
        ans=(tmp%mod*qpow(cnt,mod-2)%mod)%mod;
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    分页bootstrap
    导航条bootstrap
    导航bootstrap
    栅格系统bootstrap
    「ICPC2015 WF」Pipe Stream
    「LOJ#3399」Communication Network
    「WC2019」数树
    「UTR #3」量子破碎
    XJOI1105模拟赛 积木游戏
    XJOI1104NOIP模拟赛
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13844723.html
Copyright © 2011-2022 走看看