LOJ#6118 鬼牌
\(\rm upd\):是我假了...这题没有爆精...大家要记得这道题是相对误差\(10^{-6}\)...感谢@foreverlasting的指正。
题是好题,可是标算爆精是怎么回事...要写的和标算一毛一样才能过。
各位要写的话过了前5个点就当过了吧...
题意
你有\(n\)张牌,每张牌上有一个\(1\sim m\)的点数,你每次随机选出两张不同的牌\(A\)和\(B\),并将\(A\)的点数变为\(B\)的点数。求将所有牌的点数变成一样的期望步数。用\(double\)输出。\(n\leq 10^9\),\(m\leq 10^5\)。
题解
那首先有个挺显然的想法是枚举最终变成了哪种牌,那么所有牌就变成了是这种牌与不是这种牌两类。我们这么计算这种情况的贡献:
假如若干步以后,是这种牌的数量变为\(0\),则这种情况的贡献为\(0\)。
否则,若干步以后是这种牌的数量变为\(n\),则这种情况的贡献为\(发生的概率*步数\)。
那么只要把每种牌的这个答案加起来就好了。
现在我们要解决的问题是:有两种牌,第一种有\(i\)张,第二种有\(n-i\)张,问最终全变为第一种牌的贡献。
很显然当\(n\)固定的时候,答案只和\(i\)有关。于是我们将其记为\(f_i\)。
在计算\(f_i\)之前,我们先来计算辅助数组\(g\)。其中\(g_i\)表示有两种牌,第一种有\(i\)张,第二种有\(n-i\)张,问最终全变为第一种牌的概率。
怎么求\(g_i\)呢?首先边界条件有\(g_0=0\),\(g_n=1\),再来考虑一般的情况。
我们来考虑一下第一次对牌数有影响的操作。假如\(A\)是第一种牌,\(B\)是第二种牌,那么第一种牌数\(-1\);假如\(A\)是第二种牌,\(B\)是第一种牌,那么第一种牌数\(+1\)。显然这两种情况的方案数是一样的,于是可以得出\(i\)会等概率变成\(i-1\)或\(i+1\),于是就可以得到一个简单的式子:
\[g_i=\frac{1}{2}(g_{i-1}+g_{i+1})\]
于是移项得到:
\[g_{i+1}=2*g_i-g_{i-1}\]
可以发现每一项都依赖前两项,于是我们设\(g_1=x\),则可计算出\(g_2=2*x\),\(g_3=3*x\),\(\dots\),那么显然我们可以猜想\(g_i=i*x\),可以通过归纳法证明其是成立的。
于是得到\(g_n=n*x=1\),解得\(x=\frac{1}{n}\)。
因此当第一种牌数为\(i\)时,最终全变成第一种牌的概率为\(\frac{i}{n}\)。
现在来考虑求\(f_i\),边界条件有\(f_0=0\),\(f_n=0\),一般情况显然还是可以归纳成\(f_{i-1}\)和\(f_{i+1}\)的情况。不过这次还要额外考虑一些事情:
以变成\(i-1\)为例,首先我们枚举在几步以后变成\(i-1\)。设没有影响的操作发生概率为\(p\),使\(i\)变为\(i-1\)的操作发生概率为\(q\)。则可得到期望额外花费的步数为:
\[\sum_{j\geq 0}\Big((j+1)*p^j*q\Big)\]
整理得其为\(\frac{q}{(1-p)^2}\)。
还要注意的是由于规约到\(i-1\)的情况后成功的概率是\(\frac{i-1}{n}\),而失败的贡献是\(0\),因此期望步数只有\(\frac{i-1}{n}\)是有效的,贡献为\(\frac{q}{(1-p)^2}*\frac{i-1}{n}\)。
对于\(i+1\)的情况,\(p\)和\(q\)是一样的,因此贡献为\(\frac{q}{(1-p)^2}*\frac{i+1}{n}\)。两者相加为\(\frac{q}{(1-p)^2}*\frac{2*i}{n}\)。
可以计算得\(1-p=\frac{2*i*(n-i)}{n*(n-1)}\),\(q=\frac{i*(n-i)}{n*(n-1)}\)。于是原式可化简为:
\[\frac{n-1}{2*(n-i)}\]
因此可以得到:
\[f_i=\frac{1}{2}(f_{i-1}+f_{i+1})+\frac{n-1}{2*(n-i)}\]
移项可得:
\[f_{i+1}=2*f_i-f_{i-1}-\frac{n-1}{n-i}\]
依然设\(f_1=x\),则\(f_2=2*x-\frac{n-1}{n-1}\),\(f_3=3*x-2*\frac{n-1}{n-1}-\frac{n-1}{n-2}\),\(\dots\),依然可以通过观察和归纳法证明:
\[f_i=i*x-\sum_{j=1}^{i-1}\Big((i-j)*\frac{n-1}{n-j}\Big)\]
那么对于\(f_n\):
\[f_n=n*x-\sum_{j=1}^{n-1}\Big((n-j)*\frac{n-1}{n-j}\Big)=0\]
可解得\(x=\frac{(n-1)*(n-1)}{n}\)。
于是继续对\(f_i\)的式子进行化简:
\[f_i=i*\frac{(n-1)*(n-1)}{n}-i*(n-1)*\Big(\sum_{j=1}^{i-1}\frac{1}{n-j}\Big)+(n-1)*\Big(\sum_{j=1}^{i-1}\frac{j}{n-j}\Big)\]
我们设\(H_i\)为调和数,即\(H_i=\sum_{j=1}^{i}\frac{1}{j}\),则第二项等于:
\[-i*(n-1)*(H_{n-1}-H_{n-i})\]
继续推导第三项:
\[(n-1)*\Big(\sum_{j=1}^{i-1}\frac{j}{n-j}\Big)\]
\[(n-1)*\Big(\sum_{j=1}^{i-1}\big(\frac{n}{n-j}-1\big)\Big)\]
\[(n-1)*n*\Big(\sum_{j=1}^{i-1}\frac{1}{n-j}\Big)-(n-1)*(i-1)\]
\[(n-1)*n*(H_{n-1}-H_{n-i})-(n-1)*(i-1)\]
将三项合并,最终得到:
\[f_i=i*\frac{(n-1)*(n-1)}{n}+(n-1)*(n-i)*(H_{n-1}-H_{n-i})-(n-1)*(i-1)\]
那么问题来了,\(n\)那么大,\(H_n\)怎么求呢?标算的做法是将小的调和数预处理,大的用\(H_x\simeq \ln x+\gamma\)来近似,其中\(\gamma\)为欧拉常数。但是不知道为啥标算的\(\gamma\)取的是\(0.57\)...不过实测下来就算预处理前\(2^{20}\)的调和数以及用较精确的欧拉常数后面的误差也在\(10^{-7}\)左右...再乘以一个大常数算答案精度堪忧。
这里再提供一个精度靠谱复杂度也有保证的做法。注意到答案中计算贡献的调和数其实类似于倒数的后缀和,因此\(i\)较小的时候显然可以预处理。可以设一个阈值\(T\),预处理前\(T\)个后缀和,剩下的数不会超过\(\frac{n}{T}\)个,可以用分段打表暴力处理。由于查询量不是很大,打表的间隔可以取大一点减少代码长度。
还有由于答案有点大最好开\(long\ double\)或者自己写精度更高的类型...不过反正标算都爆精了这些好像也是后话了。这么好的题为什么不取模呢,用第二种做法就很靠谱了。
LOJ#6118 鬼牌的更多相关文章
- [loj6118]鬼牌
枚举最终所有牌的大小$i$,对于最终所有牌大小都为$i$的情况,令其贡献为步数,否则令其贡献为0,记$F$为期望贡献(即所有情况概率*贡献之和),答案即为$\sum_{i=1}^{m}F$ 显然,$F ...
- UOJ147 斗地主
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关 系根据牌的数码表示如下:3<4&l ...
- UOJ 151 斗地主“加强”版
#151. [NOIP2015]斗地主“加强”版 统计 描述 提交 自定义测试 本题开放Hack 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54 ...
- FZU 2216 The Longest Straight(最长直道)
Description 题目描述 ZB is playing a card game where the goal is to make straights. Each card in the dec ...
- Pandas python
原文: https://github.com/catalystfrank/Python4DataScience.CH 和大熊猫们(Pandas)一起游戏吧! Pandas是Python的一个 ...
- Python数据分析入门之pandas基础总结
Pandas--"大熊猫"基础 Series Series: pandas的长枪(数据表中的一列或一行,观测向量,一维数组...) Series1 = pd.Series(np.r ...
- 扑克牌(cards)
扑克牌 思路 这题也是二分!! 我们二分有几套牌,然后再去检验是否符合,至于怎么想到的,不要问我,我也不知道 那么我们主要解决的就是check函数 我们将二分的套数和每种牌的数量进行比较,如果该种牌的 ...
- Codeforces 1392H - ZS Shuffles Cards(DP+打表找规律)
Codeforces 题面传送门 & 洛谷题面传送门 真·两天前刚做过这场的 I 题,今天模拟赛就考了这场的 H 题,我怕不是预言带师 提供一种奇怪的做法,来自于同机房神仙们,该做法不需要 M ...
- Solution -「CF 1392H」ZS Shuffles Cards
\(\mathcal{Description}\) Link. 打乱的 \(n\) 张编号 \(1\sim n\) 的数字排和 \(m\) 张鬼牌.随机抽牌,若抽到数字,将数字加入集合 \(S ...
随机推荐
- 蓝桥杯 历届试题 约数倍数选卡片 (经典数论+DFS)
闲暇时,福尔摩斯和华生玩一个游戏: 在N张卡片上写有N个整数.两人轮流拿走一张卡片.要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数.例如,某次福尔摩斯拿走的卡片上写着数字“6”,则接下来华生可 ...
- 网络对抗技术 2017-2018-2 20155215 Exp9 Web安全基础
1.实践过程 前期准备:WebGoat WebGoat分为简单版和开发板,简单版是个Java的Jar包,只需要有Java环境即可,我们在命令行里执行java -jar webgoat-containe ...
- 2017-2018-2 20155224『网络对抗技术』Exp8:Web基础
实践具体要求 Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. Web前端javascipt(0.5分) 理 ...
- 全方位Bindind分析
Binding,音译为绑定,通道捆她想一条数据的高速绑着“源”与“目标”: “源”乃提供数据的一方:“目标”乃接收数据并作出相应反应的一方: 过程感觉就像是,给一个“激励”,就会作出“反应”那样--- ...
- idea 解决 pom.xml 中,maven仓库无法导入的问题(红线)
只需要用另一篇文章的 maven clean install 功能就行了 idea Cannot Resolve Symbol 问题解决
- JS跨浏览器的事件处理
1. 事件流 事件:用户或浏览器自身执行的某种动作.如click(点击事件).mouse***(鼠标事件). 事件流:页面中接收事件的顺序,也可理解为事件在页面中传播的顺序. DOM事件流包括三个阶段 ...
- Python+Selenium+Unittest+Ddt+HTMLReport分布式数据驱动自动化测试框架结构
1.Business:公共业务模块,如登录模块,可以把登录模块进行封装供调用 ------login_business.py from Page_Object.Common_Page.login_pa ...
- 软件测试为何我会首选Python
对于软件测试选择什么样的语言去学习,不同的人有不同的回答,为什么我会首选Python呢?这就要从Python的特点与适应领域说了. 一.Python的特点:优雅.明确.简单. 二.Python适合的领 ...
- SPIR-V*:面向 OpenCL™ 工作负载的英特尔® 显卡编译器默认接口
英特尔® 显卡编译器最近从 SPIR* 转换到 SPIR-V*,作为面向 OpenCL™ 工作负载的中间表示.这看起来像编译器的内部变化,对用户来说不可见,但是这展示了我们支持 Khronos* 开放 ...
- java中多态的实现机制
多态的概念: 简单来说就是事物在运行过程中存在的不同状态,即父类或接口定义的引用变量指向子类或具体实现类的实例对象.程序调用方法在运行期才进行动态绑定,而不是引用变量的类型中定义的方法. 多态存在的前 ...