標籤:子集 原因 為什麼 最新 space 指定 scanf 自己 列表
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 147 Solved: 75
Description
【故事背景】
JYY趕上了互連網創業的大潮,為非常勿擾開發了最新的手機App實現單身大齡青年之間的“速配”。然而隨著使用者數量的增長,JYY發現現有速配的演算法似乎很難滿足大家的要求,因此JYY決定請你來調查一下其中的原因。
【問題描述】
應用的後台一共有N個女性和M個男性,他們每個人都希望能夠找到自己的合適伴侶。為了方便,每個男性都被編上了1到N之間的一個號碼,並且任意兩個人的號碼不一樣。每個女性也被如此編號。
JYY應用的最大特點是賦予女性較高的選擇權,讓每個女性指定自己的“如意郎君列表”。每個女性的如意郎君列表都是所有男性的一個子集,並且可能為空白。如果列表非空,她們會在其中選擇一個男性作為自己最終接受的對象。
JYY用如下演算法來為每個女性速配最終接受的男性:將“如意郎君列表”中的男性按照編號從小到大的順序呈現給她。對於每次呈現,她將獨立地以P的機率接受這個男性(換言之,會以1−P的機率拒絕這個男性)。如果她選擇了拒絕,App就會呈現列表中下一個男性,以此類推。如果列表中所有的男性都已經呈現,那麼中介所會重新按照列表的順序來呈現這些男性,直到她接受了某個男性為止。
顯然,在這種規則下,每個女性只能選擇接受一個男性,而一個男性可能被多個女性所接受。當然,也可能有部分男性不被任何一個女性接受。這樣,每個女性就有了自己接受的男性(“如意郎君列表”為空白的除外)。現在考慮任意兩個不同的、如意郎君列表非空的女性a和b,如果a的編號比b的編號小,而a選擇的男性的編號比b選擇的編號大,那麼女性a和女性b就叫做一對不穩定因素。
由於每個女性選擇的男性是有一定的隨機性的,所以不穩定因素的數目也是有一定隨機性的。JYY希望你能夠求得不穩定因素的期望個數(即平均數目),從而進一步研究為什麼速配演算法不能滿足大家的需求。
Input
輸入第一行包含2個自然數N,M,表示有N個女性和N個男性,以及所有女
性的“如意郎君列表”長度之和是M。
接下來一行一個實數P,為女性接受男性的機率。
接下來M行,每行包含兩個整數a,b,表示男性b在女性a的“如意郎君列表”
中。
輸入保證每個女性的“如意郎君列表”中的男性出現切僅出現一次。
1≤N,M≤500,000,0.4≤P<0.6
Output
輸出1行,包含一個實數,四捨五入後保留到小數點後2位,表示不穩定因素的期望數目。
Sample Input5 5
0.5
5 1
3 2
2 2
2 1
3 1Sample Output0.89HINTSource
By 佚名上傳
數學問題 期望 腦洞題
期望還能這麼玩兒,真的神奇。
女方如果選中某個人,可能是第一輪選中的,也可能是第一輪沒選人,在第二輪選中的,也可能在第三輪,第四輪……
看上去是個無限項的等比數列求和。
利用等比數列公式計算女方選某個人的機率:
$ \frac{a_1*(1-p^n)}{1-p}$
在n無窮大的時候$ p^n $趨近於0,可以直接忽視掉。
這樣就可以算出這個位置被選的機率。
這樣,之後開始選擇的女方如果選了某個更靠前位置,就多了這麼些機率貢獻一個逆序對。
將邊按雙關鍵字排序,用樹狀數組維護一個類似逆序對的東西即可。
數據卡精度,需要long double
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cmath> 6 #include<cstring> 7 using namespace std; 8 const int mxn=500010; 9 int read(){10 int x=0,f=1;char ch=getchar();11 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}12 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}13 return x*f;14 }15 struct edge{16 int x,y;17 bool operator < (const edge &b)const{18 return ((x==b.x && y<b.y) || x<b.x);19 }20 }a[mxn],c[mxn];21 //22 int n,m;23 int len[mxn];24 long double P,pr[mxn];25 long double t[mxn];26 void add(int x,double v){while(x<=n){t[x]+=v;x+=x&-x;}}27 long double ask(int x){double res=0.0;while(x){res+=t[x];x-=x&-x;}return res;};28 inline long double GetP(int x,int y){return P*pr[y-1]/(1-pr[len[x]]);}29 int main(){30 // freopen("in.txt","r",stdin);31 n=read();m=read();scanf("%Lf",&P);32 pr[0]=1.0;33 for(int i=1;i<=m;i++){pr[i]=pr[i-1]*(1-P);}34 for(int i=1;i<=m;i++){35 a[i].x=read();a[i].y=read();len[a[i].x]++;36 }37 sort(a+1,a+m+1);38 long double ans=0.0;39 int hd=1;40 for(int i=1;i<=n;i++){//枚舉左邊41 if(a[hd].x!=i)continue;42 int cnt=0;43 while(a[hd].x==i){44 ++cnt;45 add(a[hd].y,GetP(i,cnt));46 ans+=GetP(i,cnt)*(ask(n)-ask(a[hd].y));47 hd++;48 }49 }50 printf("%.2f\n",(double)ans);51 return 0;52 }
Bzoj4481 [Jsoi2015]非誠勿擾