有 堆石子,依次編號爲 ,其中第 堆有 顆石子
你每次在仍然有石子的石子堆中等概率隨機選擇一堆石子,並取走其中一顆石子
求第 堆石子被取走的時間的期望
這題其實也不難,然而也不是考慮,和stone一樣
問題要求的實際就是在第堆石子被取完之前,總共有多少個石子被拿走了
顯然被拿完了,再考慮期望的線性性,由於你取走其他堆石子對當前堆沒有影響,可以單獨考慮每一堆石子被取了多少個
先考慮沒有全部被取完
假設第堆石子被取走了顆石子,因爲第堆石子沒被取完,而沒有繼續被取走肯定是因爲第堆石子被取完了
設爲從第一堆石子中取一顆石子,爲從第二堆石子中取一顆石子
那麼方案數就是有個和個的長度爲的且最後一位是的二進制串的個數
則有種方案數,總方案數爲,那麼概率就是
若,這個看起來沒原來那麼好算了,想到這兩種情況的概率加起來應該等於,所以這種情況的概率就是
則我們得到
總期望就是,寫複雜點就是
這個東西怎麼維護呢,直接考慮變成的情況,我們考慮裏面那個的變化,實際上只有枚舉上界增大變成了我們直接對的所有取值的答案都預處理出來就行了
/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年11月08日 星期五 16時20分30秒
*******************************/
#include <cstdio>
#include <fstream>
using namespace std;
const int maxn = 1000006;
const int lim = 1000000;
const int h = 500000;
const int mod = 323232323;
//cin爲我打的快讀板子,詳細內容可去看以前的代碼,總是在這裏寫感覺有點影響閱讀
int n,p,ans,a;
int fac[maxn],ifac[maxn],inv[maxn],mi[maxn],f[maxn],g[maxn];
int C (int n,int m){ return 1ll*fac[n]*ifac[n-m]%mod*ifac[m]%mod;}
int main()
{
fac[0]=ifac[0]=mi[0]=inv[1]=1;
for (int i=2;i<=lim;++i) inv[i]=(mod-1ll*mod/i*inv[mod%i]%mod);
for (int i=1;i<=lim;++i) fac[i]=1ll*fac[i-1]*i%mod,ifac[i]=1ll*ifac[i-1]*inv[i]%mod,mi[i]=1ll*mi[i-1]*inv[2]%mod;
cin>>n>>a;
ans=a;
//枚舉上界爲i
g[0]=mi[a];
for (int i=1;i<=h;++i){
int p=1ll*C(a+i-1,i)*mi[a+i]%mod;
f[i]=(f[i-1]+1ll*i*p%mod)%mod;
g[i]=(g[i-1]+p)%mod;
}
//石子數爲i的答案
for (int i=h;i>=1;--i) f[i]=(f[i-1]+1ll*i*(mod+1-g[i-1])%mod)%mod;
for (int i=2;i<=n;++i) cin>>a,ans=(ans+f[a])%mod;
printf("%d\n",ans);
return 0;
}
如有哪裏講得不是很明白或是有錯誤,歡迎指正
如您喜歡的話不妨點個贊收藏一下吧