剛開始你有乙個數字 \(0\),每一秒鐘你會隨機選擇乙個 \([0,2^n-1]\) 的數字,與你手上的數字進行或(c++,c 的|
,pascal 的or
)操作。選擇數字 \(i\) 的概率是 \(p_i\)。保證 \(0\leq p_i \leq 1\),\(\sum p_i=1\) 。問期望多少秒後,你手上的數字變成 \(2^n-1\)。
設 \(s\) 為全集 (\(s=\\)),設 \(e(x)\) 表示 \(x\) 被包含於得到的數字數字的期望次數,根據 min-max 容斥,有
\[e(\max(s))=\sum_(-1)^e(\min(t))
\]其中 \(e(\max(s))=e(2^n-1)\) 即為我們所求。
考慮如何求出 \(e(\min(t))\)。顯然 \(e(\min(t))\) 等於「一直在 \([0,2^n-1]\) 中隨機取數,直到取到乙個數 \(x\ \mathrm\ t\neq \varnothing\) 的期望次數」。
設 \(f(t)\) 表示在 \([0,2^n-1]\) 中隨機取數,取到 \(t\) 子集內的數的期望。那麼
\[f(t)=\fracp(x)}
\]這個東西就是子集卷積,直接上 fwt 即可。
那麼\[e(\min(t))=\frac\ s)e(\min(t))+1)+1}=\frac\ s)}
\]這樣就在 \(o(2^nn)\) 內搞定了這道題。
#include using namespace std;
const int n=(1<<20)+10;
const double eps=1e-12;
int n,lim,bit[n];
double ans,p[n];
int main()
for (int i=1;iprintf("%.10lf",ans);
return 0;
}
洛谷 P3175 HAOI2015 按位或
與hdu4336 card collector相似,使用min max容斥。設 max s 表示集合 s 中最後一位出現的期望時間。設 min s 表示集合 s 中最初一位出現的期望時間。由min max容斥可得 max t sum limits 1 min s 考慮求每乙個 min s 乙個很顯然...
洛谷 P1013 進製位
題目描述 著名科學家盧斯為了檢查學生對進製的理解,他給出了如下的一張加法表,表中的字母代表數字。例如 l k v e l l k v e k k v e kl v v e kl kk e e kl kk kv 其含義為 l l l,l k k,l v v,l e e k l k,k k v,k v ...
洛谷P3760異或和
傳送門啦 傳送門啦 一般這種位運算的題都要把每一位拆開來看,因為位運算每個位的結果這和這一位的數有關。這樣我們用s i 表示a的字首和,即 a 1 a 2 a i 然後我們從這些數二進位制最右位 2 0 開始,按照每一位對答案的貢獻來計算。假設我們現在算到最右位 2 0 並且位於第i個數,我們想要知...