• 【bzoj5091】摘苹果 概率


    题目描述

    小Q的工作是采摘花园里的苹果。在花园中有n棵苹果树以及m条双向道路,苹果树编号依次为1到n,每条道路的两端连接着两棵不同的苹果树。假设第i棵苹果树连接着d_i条道路。小Q将会按照以下方式去采摘苹果:
    1.小Q随机移动到一棵苹果树下,移动到第i棵苹果树下的概率为d_i/(2m),但不在此采摘。
    2.等概率随机选择一条与当前苹果树相连的一条道路,移动到另一棵苹果树下。
    3.假设当前位于第i棵苹果树下,则他会采摘a_i个苹果,多次经过同一棵苹果树下会重复采摘。
    4.重复第2和3步k次。
    请写一个程序帮助计算小Q期望摘到多少苹果。

    输入

    第一行包含三个正整数n,m,k(n,k<=100000,m<=200000),分别表示苹果树和道路的数量以及重复步骤的次数。
    第二行包含n个正整数,依次表示a_1,a_2,...,a_n(1<=a_i<=100)。
    接下来m行,每行两个正整数u,v(1<=u,v<=n,u!=v),表示第u和第v棵苹果树之间存在一条道路。

    输出

    若答案为P/Q,则输出一行一个整数,即P*Q^{-1} mod 1000000007(10^9+7)。

    样例输入

    3 4 2
    2 3 4
    1 2
    1 2
    2 3
    3 1

    样例输出

    750000011


    题解

    概率

    对于第 $i$ 个点,它第0次移动时的概率为 $d_i/2m$ ,其第一次移动时的概率为: $sumlimits_{<i,j>}d_j/2m/d_j=d_i/2m=d_i/2m$

    (这绝对不是巧合。。。)

    因此任何时候,到达第 $i$ 个点的概率都是 $d_i/2m$ ,因此答案就是 $k·sumlimits_{i=1}^nfrac{a_id_i}{2m}$ 。

    #include <cstdio>
    #define mod 1000000007
    typedef long long ll;
    int a[100010] , d[100010];
    ll pow(ll x , ll y)
    {
        ll ans = 1;
        while(y)
        {
            if(y & 1) ans = ans * x % mod;
            x = x * x % mod , y >>= 1;
        }
        return ans;
    }
    int main()
    {
        int n , m , k , i , x , y;
        ll ans = 0;
        scanf("%d%d%d" , &n , &m , &k);
        for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]);
        for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &x , &y) , d[x] ++ , d[y] ++ ;
        for(i = 1 ; i <= n ; i ++ ) ans += a[i] * d[i];
        printf("%lld
    " , ans * k % mod * pow(2 * m , mod - 2) % mod);
        return 0;
    }
    

     

  • 相关阅读:
    set-rebgin
    HTML5开发学习:本地存储Web Sql Database
    Sublime text 入门学习资源篇及其基本使用方法
    web前端不可错过的开发工具–Adobe Brackets
    关于WEB前端开发的工具
    WebStorm使用技巧
    五大浏览器兼容性
    IT解惑真经
    win7下一劳永逸地解决触控板禁用的问题
    PHP+Mysql学习笔记
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8016877.html
Copyright © 2020-2023  润新知