1. 程式人生 > >名校聯賽DAY.2A層第三題book(書)題解

名校聯賽DAY.2A層第三題book(書)題解

但是 con 二本 nbsp amp out 輸出 期望值 through

時間限制: 1 Sec 內存限制: 512 MB

題目描述

book.in/.out

Hazel有n本書,編號1為n到 ,疊成一堆。當她每次抽出一本書的時候,上方的書會因重力而下落,這本被取出的書則會被放置在書堆頂。

每次有pi的概率抽取編號為i的書。她每次抽書所消耗的體力與這本書在這堆中是第幾本成正比。具體地,抽取堆頂的書所耗費體力值為1 ,抽取第二本耗費體力值為2 ,以此類推。

現在 想知道,在很久很久以後(可以認為幾乎是無窮的),她每次抽書所耗費的體力的期望值是多少。

最終的答案顯然可以表示成a/b的形式,請輸出a*(b^-1)模1e9+7的值。

【輸入格式】

第一行一個整數n

接下來n行,每行兩個整數ai,bi,代表抽取第i本書的概率是ai/bi

保證所有書的概率和等於1

【輸出格式】

輸出一行一個整數,代表期望值

【輸入樣例1】

2

227494 333333

105839 333333

【輸出樣例1】

432679642

【輸入樣例2】

10

159073 999999

1493 142857

3422 333333

4945 37037

2227 111111

196276 999999

190882 999999

142721 999999

34858 999999

101914 999999

【輸出樣例2】

871435606

【數據規模與約定】

對於30%的數據,1<=n<=10。

對於100%的數據,1<=n<=1000,0<=ai<=bi,bi!=0。

  首先先吐槽一下這次考試,題目名字就不能正常一點嗎?!

  但是這道題確實不容小覷,堂堂名校聯賽50多個選手竟然全部爆零,連一個拿暴力分的人都沒有,當然包括本蒟蒻,只能呵呵。考試的時候都快絕望了,什麽題啊,根本沒思路,以為自己完了,想了兩個小時,輸出個樣例完了,天知道大家都掛了。

  然而,WQ大佬成功打出了暴力,然而只能幹掉≤9的數據,然而最小的數據正好是10。2333,但還是orz。

  其實這道題的正解真的很水,十分的水,水道比第二題水。

  首先先科普一下,除法無法像加法減法乘法那樣取模,在模意義下的除法a*(b^-1)=a/b=a*b的逆元怎麽又是它?

  然後讓我們把問題化簡一下,如果我們把所有書分開來看的話答案就是拿每本書的期望體力乘以拿這本書的概率的總和,既然在這之中後者是已知的,那我們只要求出來這本書之上有多少本書的期望即可,那麽,如果書a在書b之上,那麽既然是由於翻了無數次那麽a一定比b晚被拿出來,因此這個事件的概率就是a/(a和b被取出來的概率和),於是這道題就搞定了,最後不要忘了加上b自己就在第一個的概率。

技術分享
 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<map>
 9 #include<cmath>
10 #include<set>
11 using namespace std;
12 int n,p=1e9+7;
13 long long exgcd(long long a,long long b,long long c){
14     if(a==0)return -1;
15     else if((c%a)==0) return c/a;
16     long long t=exgcd(b%a,a,((-c%a)+a)%a);
17     if(t==-1)return -1;
18     return (t*b+c)/a;
19 }
20 long long a[1005],b[1005];
21  
22 int main(){
23     scanf("%d",&n);
24     for(int i=1;i<=n;i++)
25     {
26         scanf("%lld%lld",&a[i],&b[i]);
27         b[i]=exgcd(b[i],p,1);
28         b[i]%=p;
29         a[i]*=b[i];
30         a[i]%=p;
31     }
32     long long ans=0;
33     for(int i=1;i<=n;i++)
34     {
35         long long an=0;
36         for(int j=1;j<=n;j++)
37         {
38             if(j==i) continue;
39             long long x=a[j],y=a[i]+a[j];
40             y=exgcd(y,p,1);
41             y%=p;
42             x*=y;
43             x%=p;
44             an+=x;
45             an%=p;
46         }
47         an++;
48         an*=a[i];
49         an%=p;
50         ans+=an;
51         ans%=p;
52     }
53     printf("%lld\n",ans);
54 //  while(1);
55     return 0;
56 }
View Code

名校聯賽DAY.2A層第三題book(書)題解