题目链接:洛谷

题目大意:给定正整数 $n$。一开始有一个数字 $0$,然后每一秒,都有 $p_i$ 的概率获得 $i$ 这个数 $(0\le i< 2^n)$。一秒恰好会获得一个数。每获得一个数,就要将我们有的数与获得的数进行按位或。问期望经过多少秒后,我们的数变成 $2^n-1$。

$1\le n\le 20,\sum p_i=1$。


%%%stO shadowice1984 Orz%%%

首先定义 $\min(S)$ 表示 $S$ 中第一个变为 $1$ 的元素的时间。(其中 $S$ 是一个二进制数,是 $1$ 的位表示这一位计入答案)

$\max(S)$ 表示最后一个变为 $1$ 的元素的时间。这也符合 $\min$ 和 $\max$ 的定义。

(以下定义全集 $U=2^n-1$)

我们要求的就是 $E(\max(U))$。

容斥:$E(\max(U))=\sum\limits_{S\neq\varnothing}(-1)^{|S|+1}E(\min(S))$

现在问题就是求 $E(\min(S))$,就是有元素变为 $1$。

套期望的公式:$E(\min(S))=\sum\limits^{+\infty}_{i=1}iP(\min(S)=i)$

$P(\min(S)=i)$ 表示恰好在第 $i$ 秒出现 $1$ 的概率。

前 $i-1$ 秒都没有出现,所以应该是 $\sum\limits_{T\cap S=\varnothing}P(T)$。其中 $P(T)$ 表示出现的数是 $T$ 的概率。

第 $i$ 秒有出现,所以应该是 $1-\sum\limits_{T\cap S=\varnothing}P(T)$。

乘法原理,$P(\min(S)=i)=(\sum\limits_{T\cap S=\varnothing}P(T))^{i-1}(1-\sum\limits_{T\cap S=\varnothing}P(T))$

那么经过一通爆算,$E(\min(S))=\dfrac{1}{1-\sum\limits_{T\cap S=\varnothing}P(T)}$。

转换一下:$E(\min(S))=\dfrac{1}{1-\sum\limits_{T\subseteq\complement_US}P(T)}$。

现在最严峻的问题就是计算每个集合的子集和。

最裸的枚举,$O(4^n)$。

技巧一点的枚举,$O(3^n)$。

那么就要说到一个很有趣的事情了,我也是做了这题才知道的……

回想一下FWT(或者FMT)做按位或卷积的时候:

$C_i=\sum\limits_{j|k=i}A_jB_k$

令 $\widehat{C}_i=\sum\limits_{j\subseteq i}C_j$

那么就有 $\widehat{C}_i=\sum\limits_{j|k\subseteq i}A_jB_k$

也就是 $\widehat{C}_i=\sum\limits_{j\subseteq i,k\subseteq i}A_jB_k$

也就是 $\widehat{C}_i=\widehat{A}_i\widehat{B}_i$!

于是需要一种从 $A$ 到 $\widehat{A}$ 的变换还有它的逆变换。

于是就有了FWT(或者FMT)……

(所以说,FWT比FFT要好理解,那就要理解啊)

那么我们就知道了,FWT的或变换一次后新的序列就是原序列的子集和形式!

好的,时间复杂度 $O(n2^n)$。

代码:(实际上特别好写)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=;
  4. #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
  5. #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
  6. #define MEM(x,v) memset(x,v,sizeof(x))
  7. inline int read(){
  8. char ch=getchar();int x=,f=;
  9. while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
  10. while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
  11. return f?-x:x;
  12. }
  13. int n,cnt[maxn];
  14. double p[maxn];
  15. void FWTor(double *A){
  16. for(int i=;i<<<n;i<<=)
  17. for(int j=,r=i<<;j<<<n;j+=r)
  18. FOR(k,,i-) A[i+j+k]+=A[j+k];
  19. }
  20. int main(){
  21. n=read();
  22. FOR(i,,(<<n)-) scanf("%lf",p+i);
  23. FWTor(p);
  24. FOR(i,,(<<n)-) cnt[i]=cnt[i>>]+(i&);
  25. double ans=;
  26. FOR(i,,(<<n)-){
  27. if(-p[((<<n)-)^i]<1e-) return puts("INF"),;
  28. ans+=/(-p[((<<n)-)^i])*(cnt[i]&?:-);
  29. }
  30. printf("%.10lf\n",ans);
  31. }

[HAOI2015]按位或(min-max容斥,FWT,FMT)的更多相关文章

  1. bzoj 4036: [HAOI2015]按位或【min-max容斥+FWT】

    其实也不是FWT--我也不知道刷FWT专题问什么会刷出来这个东西 这是min-max容斥讲解:https://www.zybuluo.com/ysner/note/1248287 总之就是设min(s ...

  2. BZOJ4036 [HAOI2015]按位或 【minmax容斥 + 期望 + FWT】

    题目链接 BZOJ4036 题解 好套路的题啊,,, 我们要求的,实际上是一个集合\(n\)个\(1\)中最晚出现的\(1\)的期望时间 显然\(minmax\)容斥 \[E(max\{S\}) = ...

  3. P3175-[HAOI2015]按位或【min-max容斥,FWT】

    正题 题目链接:https://www.luogu.com.cn/problem/P3175 题目大意 开始有一个\(n\)位二进制数\(s=0\),每次有\(p_i\)概率选取数字\(i\)让\(s ...

  4. 【BZOJ4036】按位或(Min-Max容斥,FWT)

    [BZOJ4036]按位或(Min-Max容斥,FWT) 题面 BZOJ 洛谷 题解 很明显直接套用\(min-max\)容斥. 设\(E(max\{S\})\)表示\(S\)中最晚出现元素出现时间的 ...

  5. 「PKUWC2018」随机游走(min-max容斥+FWT)

    「PKUWC2018」随机游走(min-max容斥+FWT) 以后题目都换成这种「」形式啦,我觉得好看. 做过重返现世的应该看到就想到 \(min-max\) 容斥了吧. 没错,我是先学扩展形式再学特 ...

  6. 【洛谷U20626】gemo 容斥 FWT 高斯消元

    题目大意 给你一个无向图,有\(m\)个询问,每次给你一个点\(x\)和一个点集\(S\),问你从\(x\)开始走,每次从一个点随机的走到与这个点相邻的点,问你访问\(S\)中每个点至少一次的期望步数 ...

  7. BZOJ4036:按位或 (min_max容斥&高维前缀和)

    Description 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行或(c++,c的|,pascal 的or)操作.选择数字i的概率是p[i].保证0&l ...

  8. 洛谷 P5643 - [PKUWC2018]随机游走(Min-Max 容斥+FWT+树上高斯消元,hot tea)

    题面传送门 一道挺综合的 hot tea,放到 PKUWC 的 D2T2 还挺喜闻乐见的( 首先我们考虑怎样对一个固定的集合 \(S\) 计算答案,注意到我们要求的是一个形如 \(E(\max(S)) ...

  9. Min-max 容斥与 kth 容斥

    期望的线性性: \[E(x+y)=E(x)+E(y) \] 证明: \[E(x+y)=\sum_i \sum_j(i+j)*P(i=x,j=y) \] \[=\sum_i\sum_ji*P(i=x,j ...

随机推荐

  1. 初识 tk.mybatis.mapper 通用mapper

    在博客园发表Mybatis Dynamic Query后,一位园友问我知不知道通用mapper,仔细去找了一下,还真的有啊,比较好的就是abel533写的tk.mybatis.mapper. 本次例子 ...

  2. 破解Zip加密文件常用的几种方法

    前言 在互联网的浪潮中,大家也许碰到过这种情况: 从网络上下载了一个zip文件,最后却发现它是用密码保护的,或者自己用密码加密了一个很重要zip文件,但是一段时间后忘记了密码,无法打开.这个时候,我们 ...

  3. 【亲测有效】Centos安装完成docker后启动docker报错docker: unrecognized service的两种解决方案

    今天在学习Docker的时候 使用yum install docker安装完后启动不了,报错如下: [root@Sakura ~]# service docker start docker: unre ...

  4. Nginx报错: "Too many open files accept" 和 "could not build the server_names_hash"

    一.访问Nginx时,报错:"accept() failed (24: Too many open files)"原因时:nginx的连接数超过了系统设定的最大值造成的. 处理办法 ...

  5. 《Linux内核分析》期终总结&《Linux及安全》期中总结

    <Linux内核分析>期终总结&<Linux及安全>期中总结 [李行之 原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc. ...

  6. Linux课题实践三——程序破解

    2.3   程序破解 20135318 刘浩晨 1.     掌握NOP.JNE.JE.JMP.CMP汇编指令的机器码 NOP:NOP指令即“空指令”.执行到NOP指令时,CPU什么也不做,仅仅当做一 ...

  7. nginx+tpmcat+redis实现session共享

    nginx+tpmcat+redis实现session共享 版本:nginx nginx-1.8.0.tar.gztomcat apache-tomcat-7.0.78.tar.gzredis  re ...

  8. gitbub感想

    Git 是 Linux 的创始人 Linus Torvalds 开发的开源和免费的版本管理系统,利用底层文件系统原理进行版本控制的工具.Git是目前为止最著名运用最好最受欢迎的分布式的配置管理工具. ...

  9. Sprint 冲刺第三阶段第3-5天 数据库代码

    数据库代码: package com.example.brdemo; import android.app.Activity; import android.content.Intent; impor ...

  10. 编写一个shell脚本来编译并运行java代码

    概述 编译和运行java分别要用到javac命令和java命令,虽然可以使用IDE(比如eclipse,InteliJ,NetBean...),按一下快捷键就可以实现编译并运行,但是,在之前还要配置一 ...