D
e
s
c
r
i
p
t
i
o
n
\mathcal{Description}
Description
有
n
n
n 堆石子,依次编号为
1
,
2
,
…
,
n
1, 2,\ldots , n
1,2,…,n,其中第
i
i
i 堆有
a
i
a_i
ai 颗石子
你每次在仍然有石子的石子堆中等概率随机选择一堆石子,并取走其中一颗石子
求第
1
1
1 堆石子被取走的时间的期望
n ≤ 5 × 1 0 5 , a i ≤ 5 × 1 0 5 n\leq 5\times 10^5,a_i\leq 5\times 10^5 n≤5×105,ai≤5×105
S
o
l
u
t
i
o
n
\mathcal{Solution}
Solution
这题其实也不难,然而也不是考虑
D
P
DP
DP,和stone一样
问题要求的实际就是在第
1
1
1堆石子被取完之前,总共有多少个石子被拿走了
显然
a
1
a_1
a1被拿完了,再考虑期望的线性性,由于你取走其他堆石子对当前堆没有影响,可以单独考虑每一堆石子被取了多少个
先考虑
a
i
a_i
ai没有全部被取完
假设第
i
i
i堆石子被取走了
x
(
0
≤
x
≤
a
i
−
1
)
x\left(0\leq x\leq a_i-1\right)
x(0≤x≤ai−1)颗石子,因为第
i
i
i堆石子没被取完,而没有继续被取走肯定是因为第
1
1
1堆石子被取完了
设
1
1
1为从第一堆石子中取一颗石子,
0
0
0为从第二堆石子中取一颗石子
那么方案数就是有
a
1
a_1
a1个
1
1
1和
x
x
x个
0
0
0的长度为
a
1
+
x
a_1+x
a1+x的且最后一位是
1
1
1的二进制串的个数
则有
(
a
1
+
x
−
1
x
)
\begin{pmatrix}a_1+x-1 \\ x\end{pmatrix}
(a1+x−1x)种方案数,总方案数为
2
a
1
+
x
2^{a_1+x}
2a1+x,那么概率就是
p
x
=
(
a
1
+
x
−
1
x
)
2
a
1
+
x
p_x=\frac{\begin{pmatrix}a_1+x-1\\ x\end{pmatrix}}{2^{a_1+x}}
px=2a1+x(a1+x−1x)
若
x
=
a
i
x=a_i
x=ai,这个看起来没原来那么好算了,想到这两种情况的概率加起来应该等于
1
1
1,所以这种情况的概率就是
q
=
1
−
∑
j
=
0
a
i
−
1
p
j
q=1-\sum\limits_{j=0}^{a_i-1}p_j
q=1−j=0∑ai−1pj
则我们得到
E
i
=
∑
j
=
0
a
i
−
1
j
∗
p
j
+
q
a
i
E_i=\sum\limits_{j=0}^{a_i-1}j*p_j+qa_i
Ei=j=0∑ai−1j∗pj+qai
总期望就是
E
=
∑
i
=
2
n
E
i
E=\sum\limits_{i=2}^nE_i
E=i=2∑nEi,写复杂点就是
E = ( ∑ i = 2 n ( ∑ j = 0 a i − 1 j ∗ ( a 1 + j − 1 j ) 2 a 1 + j ) + a i ( 1 − ∑ j = 0 a i − 1 ( a 1 + j − 1 j ) 2 a 1 + j ) ) + a 1 E=\left(\sum\limits_{i=2}^n\left(\sum\limits_{j=0}^{a_i-1}j*\frac{\begin{pmatrix}a_1+j-1 \\ j\end{pmatrix}}{2^{a_1+j}}\right)+a_i\left(1-\sum\limits_{j=0}^{a_i-1}\frac{\begin{pmatrix}a_1+j-1 \\ j\end{pmatrix}}{2^{a_1+j}}\right)\right)+a_1 E=⎝⎛i=2∑n⎝⎛j=0∑ai−1j∗2a1+j(a1+j−1j)⎠⎞+ai⎝⎛1−j=0∑ai−12a1+j(a1+j−1j)⎠⎞⎠⎞+a1
这个东西怎么维护呢,直接考虑 a i a_i ai变成 a i + 1 a_i+1 ai+1的情况,我们考虑里面那个 ∑ \sum ∑的变化,实际上只有枚举上界增大 1 1 1变成了 a i a_i ai我们直接对 a i a_i ai的所有取值的答案都预处理出来就行了
C o d e \mathcal{Code} Code
/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年11月08日 星期五 16时20分30秒
*******************************/
#include <cstdio>
#include <fstream>
using namespace std;
const int maxn = 1000006;
const int lim = 1000000;
const int h = 500000;
const int mod = 323232323;
//cin为我打的快读板子,详细内容可去看以前的代码,总是在这里写感觉有点影响阅读
int n,p,ans,a;
int fac[maxn],ifac[maxn],inv[maxn],mi[maxn],f[maxn],g[maxn];
int C (int n,int m){ return 1ll*fac[n]*ifac[n-m]%mod*ifac[m]%mod;}
int main()
{
fac[0]=ifac[0]=mi[0]=inv[1]=1;
for (int i=2;i<=lim;++i) inv[i]=(mod-1ll*mod/i*inv[mod%i]%mod);
for (int i=1;i<=lim;++i) fac[i]=1ll*fac[i-1]*i%mod,ifac[i]=1ll*ifac[i-1]*inv[i]%mod,mi[i]=1ll*mi[i-1]*inv[2]%mod;
cin>>n>>a;
ans=a;
//枚举上界为i
g[0]=mi[a];
for (int i=1;i<=h;++i){
int p=1ll*C(a+i-1,i)*mi[a+i]%mod;
f[i]=(f[i-1]+1ll*i*p%mod)%mod;
g[i]=(g[i-1]+p)%mod;
}
//石子数为i的答案
for (int i=h;i>=1;--i) f[i]=(f[i-1]+1ll*i*(mod+1-g[i-1])%mod)%mod;
for (int i=2;i<=n;++i) cin>>a,ans=(ans+f[a])%mod;
printf("%d\n",ans);
return 0;
}
如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧