標籤:存在 class 選擇 重複 串連 sample inpu c++ problems
5091: [Lydsy0711月賽]摘蘋果Time Limit: 1 Sec Memory Limit: 256 MB
Submit: 148 Solved: 114
[Submit][Status][Discuss]Description小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期望摘到多少蘋果。 Input
第一行包含三個正整數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棵蘋果樹之間存在一條道路。 Output
若答案為P/Q,則輸出一行一個整數,即P*Q^{-1} mod 1000000007(10^9+7)。
Sample Input3 4 2
2 3 4
1 2
1 2
2 3
3 1Sample Output750000011
//期望為5.75=23/4=(23*250000002) mod 1000000007=750000011。 讓我們設f[i][j]為走了i次之後到j的機率。 顯然 f[0][j] = d[j]/2m 。 然後答案就是ΣΣf[i][j] * a[j] 但其實不管i是多少,f[i][j] 都等於 d[j]/2m ,接下來我來證明這一點。 因為f[0][j] 等於 d[j]/2m ,所以我們第一次走上每條邊(考慮方向的話是有2m條邊的)的機率都是1/2m, 所以每個點被走到的機率就是d[j]/2m,也就是f[1][j] = f[0][j] 。 然後就證出來了2333
#include<bits/stdc++.h>#define ll long longusing namespace std;const int maxn=200005;const int ha=1000000007;int inv,n,m,ans;int k,d[maxn],a[maxn];inline int add(int x,int y){x+=y;return x>=ha?x-ha:x;}inline int ksm(int x,int y){int an=1;for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;return an;}int main(){ scanf("%d%d%d",&n,&m,&k); int uu,vv; inv=ksm(2*m,ha-2);for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<=m;i++){ scanf("%d%d",&uu,&vv); d[uu]++,d[vv]++; } for(int i=1;i<=n;i++) ans=add(ans,a[i]*d[i]*(ll)inv%ha); ans=ans*(ll)k%ha; printf("%d\n",ans); return 0;}
bzoj 5091: [Lydsy0711月賽]摘蘋果