题意就是有n个人,d天。
初始每个人有一个宝石。然后每天选一颗宝石复制一份。
问d天后,宝石数量前r大的人所拥有宝石数量总和的期望。
1≤r≤n≤1.5×107,1≤d≤1.5×107
首先考虑弱化版,O(n3)的做法。
这需要一个转换:考虑一个最终状态a1,a2…an。ai表示这d天第i个人复制出来的宝石。
计算它出现的次数为(dai)×∏ai!
发现就是d!。那么所有a的概率都一样。
那么问题转换为计数a的个数(这个值就是(d+n−1n−1)),并计算所有a中前r大的钻石数量。
这个可以用一个DP完成。
就是设f[i][j]表示有j个人为当前宝石数量并列最多,已经过了i天,在这个状态下的方案数。
下面考虑优化。用式子去表达答案。
就是n∑i=1min(i,r)d∑j=1Fi,j
设Fi,j表示恰好有i个人至少有j个钻石。
这个F显然可以用二项式反演。
设Gi,j表示至少有i个人至少有j个钻石。
那么Gi,j=(ni)(d−i∗j+n−1n−1)
反演得Fi,j=n∑k=i(−1)k−i(ki)Gk,j
把G,F都带入到原式可得:
n∑i=1min(i,r)d∑j=1n∑k=i(−1)k−i(ki)(nk)(d−k∗j+n−1n−1)
整理可变成n∑k=1(nk)k∑i=1(−1)k−imin(i,r)(ki)d∑j=1(d−k∗j+n−1n−1)
考虑设Qi表示d∑i|j(d−j+n−1n−1),
设Pi表示i∑j=1(−1)i−jmin(j,r)(ij)
原始就变成了n∑k=1(nk)PkQk
显然Q是可以用高维前缀和O(nloglogn)解决的。
注意:这里可以发现Q与原始不同,多了j=0情况。意义上就是把初始钻石也加上了。所以就不用在最后加n了。
然后瓶颈在于处理P
仍然考虑推式:
i∑j=1(−1)i−jmin(j,r)(ij)
r∑l=1i∑j=l(−1)i−j(ij)
由n∑i=0(−1)i(ni)=0可推得。
−(−1)ir∑l=1l−1∑j=0(−1)j(ij)
类推上面等式,玩杨辉三角可推得
(−1)ir∑l=1(−1)l(i−1l−1)
−(−1)ir−1∑l=0(−1)l(i−1l)
(−1)i+r(i−2r−1)
所以Pi=(−1)i+r(i−2r−1)。预处理组合数后O(1)计算。
所以最大复杂度就是处理Q的mloglogm,其他都是线性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理