\(\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 鬼牌的更多相关文章

  1. [loj6118]鬼牌

    枚举最终所有牌的大小$i$,对于最终所有牌大小都为$i$的情况,令其贡献为步数,否则令其贡献为0,记$F$为期望贡献(即所有情况概率*贡献之和),答案即为$\sum_{i=1}^{m}F$ 显然,$F ...

  2. UOJ147 斗地主

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关 系根据牌的数码表示如下:3<4&l ...

  3. UOJ 151 斗地主“加强”版

    #151. [NOIP2015]斗地主“加强”版 统计 描述 提交 自定义测试 本题开放Hack 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54 ...

  4. FZU 2216 The Longest Straight(最长直道)

    Description 题目描述 ZB is playing a card game where the goal is to make straights. Each card in the dec ...

  5. Pandas python

    原文:  https://github.com/catalystfrank/Python4DataScience.CH   和大熊猫们(Pandas)一起游戏吧!   Pandas是Python的一个 ...

  6. Python数据分析入门之pandas基础总结

    Pandas--"大熊猫"基础 Series Series: pandas的长枪(数据表中的一列或一行,观测向量,一维数组...) Series1 = pd.Series(np.r ...

  7. 扑克牌(cards)

    扑克牌 思路 这题也是二分!! 我们二分有几套牌,然后再去检验是否符合,至于怎么想到的,不要问我,我也不知道 那么我们主要解决的就是check函数 我们将二分的套数和每种牌的数量进行比较,如果该种牌的 ...

  8. Codeforces 1392H - ZS Shuffles Cards(DP+打表找规律)

    Codeforces 题面传送门 & 洛谷题面传送门 真·两天前刚做过这场的 I 题,今天模拟赛就考了这场的 H 题,我怕不是预言带师 提供一种奇怪的做法,来自于同机房神仙们,该做法不需要 M ...

  9. Solution -「CF 1392H」ZS Shuffles Cards

    \(\mathcal{Description}\)   Link.   打乱的 \(n\) 张编号 \(1\sim n\) 的数字排和 \(m\) 张鬼牌.随机抽牌,若抽到数字,将数字加入集合 \(S ...

随机推荐

  1. scrapy(一)scrapy 安装问题

    一.安装scrapy pip install scrapy 二.出现Microsoft Visual C++ 14.0相关问题 注:若出现以下安装错误 building 'twisted.test.r ...

  2. Excel frequency函数

    计算连续次数最常用的函数就是FREQUENCY,下面就这个函数在计算连续次数的应用做一个详细图解.首先,我们需要了解一下FREQUENCY函数的计算原理.    FREQENCY(数据区域,用于设置区 ...

  3. SqlServer执行大的数据库脚本出错解决方法

    如果执行线上项目拷下来sqlserver的.sql的数据库脚本文件,如果文件较大时,那么就会报错内存不足之类的. 这时可以在命令提示符使用命令来执行脚本文件.切记,执行前先改一下数据库存放位置! 命令 ...

  4. jQuery.bsgrid

    http://thebestofyouth.com/bsgrid/ 支持json.xml数据格式,皮肤丰富并且容易定制,支持表格编辑.本地数据.导出参数构建等实用便捷的功能,容易扩展,更拥有丰富的示例 ...

  5. 20155222卢梓杰 实验九 Web安全基础

    实验九 Web安全基础 今天不多bb,打开webgoat就是干好吧 1.简单字符串sql注入 可以看到这个实验说明是 "下表允许用户查看其信用卡号码.尝试插入一个SQL字符串,以显示所有信用 ...

  6. 20155334 《网络攻防》 Exp7 网络欺诈防范

    20155334 <网络攻防> Exp7 网络欺诈防范 一.基础问题回答 通常在什么场景下容易受到DNS spoof攻击 同一局域网下,以及各种公共网络. 在日常生活工作中如何防范以上两攻 ...

  7. 20155338 《网络攻防》Exp5 MSF基础应用

    20155338 <网络攻防>Exp5 MSF基础应用 基础问题回答 1. 用自己的话解释什么是exploit,payload,encode? exploit将真正要负责攻击的代码传送到靶 ...

  8. 关于Trie的一些算法

    最近学习了一下关于Trie的一些姿势,感觉很实用. 终于不用每次看到字符串判重等操作就只想到hash了 关于Trie的定义,来自百度百科 在计算机科学中,Trie,又称前缀树或字典树,是一种有序树状的 ...

  9. Eclipse编辑器设置

    1. 自己不太喜欢Eclipse按回车后自动插入参数的默认选项. 可以在Window-Preferences-Java-Editor-Content Assist选项里,将Fill method ar ...

  10. docker之故障问题解决方案

    1.报错如下一 Error response from daemon: driver failed programming external connectivity on endpoint lnmp ...