Endless Spin

给你一段长度为[1..n]的白色区间,每次随机的取一个子区间将这个区间涂黑,问整个区间被涂黑时需要的期望次数。

n<=50

题解

显然是min-max容斥,但是n的范围太大,不能暴力枚举。

设计DP,令f(i,j,k)表示前i个球中必须选第i个球,有j种区间可以选择并且选择他们不会涂黑决定要涂黑的球,决定要涂黑的球的个数是奇数还是偶数的方案数。

转移就考虑第i个球必须选时,上一个决定要选的球是哪个就行了。

注意这题需要实现一个高精度。

  1. CO int N=51;
  2. LL dp[N][N*N][2];
  3. LL ans[100];
  4. IN int sec(int n){
  5. return n*(n+1)/2;
  6. }
  7. void add(LL a,LL b){
  8. ans[0]+=floor((LD)a/b),a-=floor((LD)a/b)*b;
  9. for(int i=1;i<100;++i)
  10. a*=10,ans[i]+=a/b,a%=b;
  11. }
  12. void real_main(){
  13. int n=read<int>();
  14. memset(dp,0,sizeof dp),dp[0][0][0]=1;
  15. for(int i=1;i<=n;++i)for(int j=0;j<=sec(i);++j)
  16. for(int k=i-1;k>=0;--k){ // last ball
  17. if(sec(i-k-1)>j) break;
  18. dp[i][j][0]+=dp[k][j-sec(i-k-1)][1];
  19. dp[i][j][1]+=dp[k][j-sec(i-k-1)][0];
  20. }
  21. memset(ans,0,sizeof ans);
  22. for(int i=1;i<=n;++i)for(int j=0;j<sec(i);++j)
  23. add((dp[i][j][1]-dp[i][j][0])*sec(n),sec(n)-j-sec(n-i));
  24. for(int i=99;i>=16;--i)
  25. if(ans[i]>=10) ans[i-1]+=ans[i]/10,ans[i]%=10;
  26. if(ans[16]>=5) ++ans[15];
  27. for(int i=15;i>=1;--i)
  28. if(ans[i]>=10) ans[i-1]+=ans[i]/10,ans[i]%=10;
  29. printf("%lld.",ans[0]);
  30. for(int i=1;i<=15;++i) printf("%lld",ans[i]);
  31. puts("");
  32. }
  33. int main(){
  34. // freopen("HDU4624.in","r",stdin),freopen("HDU4624.out","w",stdout);
  35. for(int T=read<int>();T--;) real_main();
  36. return 0;
  37. }

按位或

题目描述

刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行或(c++,c的|,pascal的or)操作。选择数字i的概率是p[i]。保证0<=p[i]<=1,Σp[i]=1问期望多少秒后,你手上的数字变成2^n-1。

输入格式

第一行输入n表示n个元素,第二行输入2^n个数,第i个数表示选到i-1的概率

输出格式

仅输出一个数表示答案,绝对误差或相对误差不超过1e-6即可算通过。如果无解则要输出INF

输入输出样例

输入 #1
复制

  1. 2
  2. 0.25 0.25 0.25 0.25
输出 #1
复制

  1. 2.6666666667

说明/提示

对于100%的数据,n<=20

shadowice1984的题解

min-max容斥原理

min-max容斥原理,其实就是两个很简单的等式

记\(\max(S)\)为集合S中的最大值,\(\min(S)\)为集合S中的最小值,\(|S|\)为集合\(S\)的元素数量,那么以下两个等式成立

\[\max(S)=\sum_{T\subseteq S}(-1)^{|T|+1}\min(T)\\
\min(S)=\sum_{T\subseteq S}(-1)^{|T|+1}\max(T)
\]

所谓的min-max容斥原理大概就是这两个简单的等式了,它真正暴力的地方在于我们就算根本没法进行大小比较,也可以仅通过加减法把max或者min以极其暴力的方式\(O(2^n)\)的枚举子集容斥出来

下面我们尝试着给出证明,这里只证明第一个等式好了,后边的可以自行推出

其实只需要证明一件事,就是除了\(\min(T)=\max(S)\)的那个值,其他的\(\min\)值都被消掉了就可以了(这里说明一下,我们假定集合中的元素两两相异,如果存在相同的值的话,我们给其中几个加上一些eps扰动一下即可,反正不影响最值就是了)

先来说明\(\max(S)\)的系数为什么是\(1\),假设中S最大的元素是\(a\),那么我们会发现只有\(\min(\{a\})=\max(S)\)所以\(\max(S)\)的系数必须是\(1\)

然后再说明为什么别的\(\min\)都被消掉了,假设某个元素\(b\)的排名是\(k\),那么\(\min(T)=b\)当且仅当我们选出的集合是后\(n-k\)个的元素构成的集合的子集然后并上\(\{b\}\)得到的,我们会发现显然这样的集合有\(2^{n-k}\)种,而显然这其中恰有\(2^{n-k-1}\)中是有奇数个元素的,恰有\(2^{n-k-1}\)种是有偶数个元素的,两两相消自然就成\(0\)了。当然上述等式在\(k=n\)的时候不成立,但是此时剩下的刚好是最大值,所以证明完毕。

一些推导

现在我们有了非常暴力的min-max定理了,让我们来看看我们可以干一些什么事

一个令人惊讶的事实是,min-max定理在期望下成立,我们记\(E(\max(S))\)为集合中\(\max\)值的期望,那么有

\[E(\max(S))=\sum_{T\subseteq S}(-1)^{|T|+1}E(\min(T))\\
E(\min(S))=\sum_{T\subseteq S}(-1)^{|T|+1}E(\max(T))
\]

那么如何定义在这道题里面的期望呢?

我们现在发现如果认为某个位置变为\(1\)的步数是一个随机变量的话,那么\(E(\max(S))\)可以认为是某个集合\(S\)中最晚元素出现的期望时间。(因为最晚的位置都变成\(1\)了,所有的位置自然都变成\(1\)了)

那么很现实的一个事情是,我们没法比较两个位置变成\(1\)的期望步数长短,所以我们要使用min-max容斥原理在没有办法比较大小的情况下的求出\(\max\)来

但是我们必须有一个求出\(\min\)的方式……否则min-max容斥就是白搭,也就是说我们需要求\(E(\min(T))\),即集合T中最早元素出现的期望时间。

离散随机变量的几何分布

几何分布就是这里有一个离散型随机变量\(X\),满足

\[P(x=k)=(1-p)^{k-1}p (k\in N^{+})
\]

其中\(p\)是一个常量

然后我们就说这个离散型随机变量\(X\)服从带参数\(p\)的几何分布

然后不如让我来试着求一下一个服从几何分布的随机变量的期望?

\[E(X)=\sum_{i=1}^{+ \infty}iP(x=i)
=p\sum_{i=1}^{+ \infty} i(1-p)^{i-1}
\]

然后我们发现这大概是一个等比数列*等差数列的数列求和的式子

可以算出来是这个式子

\[E(x)=p\frac{1}{1-(1-p^2)}=p\frac{1}{p^2}=\frac{1}{p}
\]

另一些推导

接着上一次推导,我们现在要求\(E(\min(T))\)了

那么我们可以发现\(P(\min(T)=k)\)的意义就是前\(k-1\)次都没有选中这个集合中的哪怕一个数,换句话来讲,前\(k-1\)次都是选了这个集合补集的子集,然后第\(k\)次没有选这个集合补集的子集,可以列出这样一个式子,我们记\(P(S)\)为选中\(S\)子集的概率之和

\[P(\min(T)=k)=P(\complement_{U}T)^{k-1}(1-P(\complement_{U}T))
\]

这是什么?我们发现\(\min(T)\)服从系数为\(1-P(\complement_{U}T)\)的几何分布!

然后期望直接套公式计算就行啦!

怎么求\(P(T)\)呢?使用快速莫比乌斯变换(FMT)即可。

时间复杂度\(O(2^nn)\)。

  1. #include<bits/stdc++.h>
  2. #define co const
  3. using namespace std;
  4. co double eps=1e-10;
  5. co int N=1<<20;
  6. int n,up,cnt[N];
  7. double p[N];
  8. int main(){
  9. scanf("%d",&n),up=(1<<n);
  10. for(int i=0;i<up;++i) scanf("%lf",p+i),cnt[i]=cnt[i>>1]+(i&1);
  11. for(int k=0;k<n;++k)
  12. for(int s=(up-1)^(1<<k),i=s;;i=(i-1)&s){
  13. p[i|(1<<k)]+=p[i];
  14. if(i==0) break;
  15. }
  16. double ans=0;
  17. for(int i=1;i<up;++i){
  18. if(1-p[(up-1)^i]<eps) return puts("INF"),0;
  19. double e=1/(1-p[(up-1)^i]);
  20. if(cnt[i]&1) ans+=e;
  21. else ans-=e;
  22. }
  23. printf("%lf\n",ans);
  24. return 0;
  25. }

HDU4624 Endless Spin 和 HAOI2015 按位或的更多相关文章

  1. 题解 hdu4624 Endless Spin

    题目链接 题目大意: 有长度为\(n\)的区间,每次随机选择一段(左右端点都是整数)染黑,问期望多少次全部染黑. \(n\leq 50\) 设\(n\)个随机变量\(t_1,...,t_n\).\(t ...

  2. HDU4624 Endless Spin 【最大最小反演】【期望DP】

    题目分析: 题目是求$E(MAX_{i=1}^n(ai))$, 它等于$E(\sum_{s \subset S}{(-1)^{|s|-1}*min(s))} = \sum_{s \subset S}{ ...

  3. HDU4624 Endless Spin(概率&&dp)

    2013年多校的题目,那个时候不太懂怎么做,最近重新拾起来,看了一下出题人当初的解题报告,再结合一下各种情况的理解,终于知道整个大致的做法,这里具体写一下做法. 题意:给你一段长度为[1..n]的白色 ...

  4. 【BZOJ4036】[HAOI2015]按位或 FWT

    [BZOJ4036][HAOI2015]按位或 Description 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行或(c++,c的|,pascal的or ...

  5. [BZOJ 4036][HAOI2015]按位或

    4036: [HAOI2015]按位或 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 746  Solved: 4 ...

  6. Endless Spin

    clj的题.图是假的别看 得先做这个[HAOI2015]按位或 本题如果还用[HAOI2015]按位或 的方法,2^50拜拜 但是思路一定是这样的:min-max容斥,考虑每个S的第一触及次数期望 这 ...

  7. [luogu 3175] [HAOI2015]按位或(min-max容斥+高维前缀和)

    [luogu 3175] [HAOI2015]按位或 题面 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行按位或运算.问期望多少秒后,你手上的数字变成2^n ...

  8. bzoj4036 / P3175 [HAOI2015]按位或

    bzoj4036 / P3175 [HAOI2015]按位或 是一个 min-max容斥 的板子题. min-max容斥 式子: $ \displaystyle max(S) = \sum_{T\su ...

  9. BZOJ4036 [HAOI2015]按位或 FWT

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4036.html 题目传送门 - BZOJ4036 题意 刚开始你有一个数字 $0$ ,每一秒钟你会随机 ...

随机推荐

  1. 【java】使用jsp命令查看系统中java运行的程序及进程号

    对于java独立运行的程序,他们在进程中的名字都是 Java(TM) Platform SE binary,如图 我们想知道这个进程运行的是哪个程序,怎么办呢? 答案是:可以在命令行下,运行:jps命 ...

  2. php filter_var()

    定义和用法 filter_var() 函数通过指定的过滤器过滤变量. 如果成功,则返回已过滤的数据,如果失败,则返回 false. 语法 filter_var(variable, filter, op ...

  3. 『2019 SummerCamp 总结』

    做题 对于习题方面,我们感觉一个暑假还是留下了不少的题要写,大部分应该是讲师讲课的例题,还有少部分考试题.考试题没有订正完是因为还有算法不会,或是因为题太毒瘤了不会.同时,也发现自己还是有很多应该学的 ...

  4. 认清楚服务器的真正身份--深入ARP工作原理

    我们知道IP地址是ISP分配给我们的,IP不能作为服务器的唯一的身份,那么服务器真正的身份是什么呢?MAC IP地址直接的通信在底层要转换到MAC直接的通信,那他们如何通信的呢? 1.简介 出场人物: ...

  5. python字符串的拼接

    方式一:使用"+"拼接(拼接字符串较多时会影响拼接效率) 方式二:使用","拼接(只能用于print打印,赋值操作会生成元组) 方式三:使用"%&qu ...

  6. 《C++ Primer》学习总结;兼论如何使用'书'这种帮助性资料

    6.25~ 6.27,用了3天翻了一遍<C++ Primer>. ▶书的 固有坏处 一句话: 代码比 文字描述 好看多了.————> 直接看习题部分/ 看demo就行了 看文字在描述 ...

  7. Docker 镜像,dump openjdk-alpine 镜像容器中的 jvm

    默认情况下,我们使用的都是 jre 版本的 openjdk,当容器启动卡住不动的时候,看不出来任何问题. 此时如果能 dump 就能知道线程在干啥,也能找到一些大概的问题. 此时 jre 版本的镜像就 ...

  8. WebStorm eslint插件报错解决 - TypeError: this.CliEngine is not a constructor

    将eslint更新版本后,出现TypeError: this.CliEngine is not a constructor的错误. 解决办法: 1.编辑 X:\WebStorm\plugins\Jav ...

  9. nodejs npm vue yarn 环境搭建

    1.nodejs中文网http://nodejs.cn/download/下载最新版本 2.安装注意,虽然.msi包没有右键用管理员权限运行,如果直接双击安装可能会存在安装失败的问题.使用管理员权限运 ...

  10. VB参考

    Open 语句: 能够对文件输入/输出 (I/O). Open pathname For mode [Access access] [lock] As [#]filenumber [Len=recle ...