结合七牛云 做视频网站/报个电脑培训班要多少钱
传送门
problem
在一条公路上,有一排摩天大楼,数量在 2∼314!2\sim 314!2∼314! 之间。每一栋大楼有一个高度(正整数),高度为 iii 的概率为 2−i2^{-i}2−i。
为了出题某种特殊原因,在大楼之间安装了一些溜索,且在某栋楼的i层和另一栋楼的i层之间有一条溜索,当且仅当这两栋楼之间没有一栋大楼高度达到 iii 层。 Alice 和 Bob 决定数一数摩天大楼的数量。
Alice 非常细心,她从最左侧的摩天大楼出发,计数器为 111。然后她向右移动,每次移到下一栋大楼,都将计数器加 111。她一直走到最右侧的大楼。(就是有多少栋数出来多少栋)。
Bob 非常没耐心,他希望尽快数完。他从最左侧的摩天大楼开始,计数器为 111。他使用溜索在大楼之间移动。每次 Bob 都用最高的溜索向右移动,但由于恐高,他会忽略掉那些编号超过 hhh 的楼层。Bob 用溜索旅行跑得比香港记者还快,以至于他根本没法数清经过了多少大楼。因此他只是将计数器加上 2i2^i2i,其中 iii 是他当前所在的楼层编号。他持续移动,直到到达最右侧的大楼。(注意编号从 000 开始)。
举个例子。有 666 栋大楼,从左到右的高度分别是 1,4,3,4,1,21,4,3,4,1,21,4,3,4,1,2,且h=2h=2h=2。Alice 开始时计数器为 111,并且将计数器加了五次 111,得到的结果是 666。Bob 开始时计数器为 111,然后他依次加上 1,4,4,21,4,4,21,4,4,2,最终得到 121212。注意,Bob 出于恐高忽略掉了最高的溜索。
当 Alice 和 Bob 到达最右端的大楼时,他们将各自的计数器拿出来比较。给出 Alice 或者 Bob 的计数器的值,你需要计算出另外一个人的计数器的期望值。
数据范围:2≤n≤300002\le n\le300002≤n≤30000,0≤h≤300\le h\le300≤h≤30。
solution
神仙数学题啊 orz。
推导过程看这里吧,我就只写结论了。
- Bob 推 Alice,ans=nans=nans=n。
- Alice 推 Bob,ans=n+∑i=1h∑j=1n(n−j)×(1−12i)j−1×(12)2i×(2i−2i−1×(1+(j−1)12i−1))ans=n+\sum\limits_{i=1}^h\sum\limits_{j=1}^n(n-j)\times (1-\frac 1{2^i})^{j-1}\times (\frac 1 2)^{2i}\times (2^i-2^{i-1}\times (1+(j-1)\frac 1{2^i-1}))ans=n+i=1∑hj=1∑n(n−j)×(1−2i1)j−1×(21)2i×(2i−2i−1×(1+(j−1)2i−11))。
code
#include<bits/stdc++.h>
using namespace std;
char S[10];
double P[35];
double power(double a,int b){double ans=1;for(;b;b>>=1,a*=a) if(b&1) ans*=a;return ans;
}
int main(){int n,h;scanf("%s%d%d",S,&n,&h),P[0]=1;for(int i=1;i<=30;++i) P[i]=P[i-1]*2;if(S[0]=='B') printf("%.9lf\n",(double)n);else{double ans=n;for(int i=1;i<=n;++i)for(int j=1;j<=h;++j)ans+=(n-i)/P[j]/P[j]*power(1.0-1.0/P[j],i-1)*(P[j]-P[j-1]*(1.0+(i-1)/(P[j]-1)));printf("%.9lf\n",ans);}return 0;
}