update 9.20:本篇题解已经被(yyb)证明是出锅的
这道题目最后的式子看上去是很简单的,不到10行就码完了,但是求式子的过程并没有那么简单。
很容易想到一种枚举思路:
因为每一段连续的1都有一个结束位置,我们从左到右枚举这个结束位置,
再枚举在这个位置结束的连续的1的长度,最后把贡献加入答案。
用式子写出来就是:
其中(p_{i,j})表示结束位置为(i)的连续1串,其长度为(j)的概率
(p_{i,j})可以预处理,这样做是(O(n^2))的
如何做到(O(n))?考虑差分
我们先从一个简单的问题开始
现在你有一个取值为([1,a])的整数随机数(x),它取(i(1le ile a))的几率为(p_i),求(E(x))
注意这里的(p)和前面的有所不同
根据数学知识我们知道(E(x)=sum_{i=1}^{a}i imes p_i)
现在我们把这个求和式子做一下变换:
第一个等号显然
第二个等号交换了一下求和的顺序(如果不知道为什么的可以手画一下(a)较小的情况)
我们记(sum_{j=i}^{a}p_j=f_i),它表示随机数的取值(ge i)的概率
于是我们现在得到了另一个公式:
从另一个角度理解这个式子:
当(a=1)时,显然(E(x)=f_1=p_1)
当(a=2)时,我们如果继续使用(f_1=p_1+p_2)作为答案,会发现我们把(x=2)对答案的贡献给算少了;
本来应该是(2 imes p_2),我们的原答案((f_1))里只有一个(p_2)
因此我们还要加上一个(f_2),即(f_1+f_2)
当(a=3)时,我们如果继续使用(f_1+f_2=p_1+2p_2+2p_3)作为答案,
会发现我们把(x=3)对答案的贡献给算少了;
本来应该是(3 imes p_3),我们的原答案((f_1+f_2))里只有两个(p_3)
因此我们还要加上一个(f_3),即(f_1+f_2+f_3)
故每当(x)的可能取值范围扩大后,我们就需要对于原来我们给出的期望进行补足
回到这道题,我们要算的是(sum_{i=1}^{n}sum_{j=1}^{i}p_{i,j}j^3)
这里的(p)是前面的(p_{i,j})
我们可以换成求(f_{i,j}),它表示结束位置为(i)的连续1串,其长度(ge j)的概率
如果我们只要算(sum_{i=1}^{n}sum_{j=1}^{i}p_{i,j}j)(没有了立方)
那么答案变成(sum_{i=1}^{n}sum_{j=1}^{i}f_{i,j})
而这里的(f_{i,j})非常好求,就是(prod_{k=i-j+1}^{i}s_k),
(s_k)表示第(k)个位置为(1)的概率
因为只要((i-j+1))到(i)的位置全部为(1),那么连续1串的长度一定(ge j)
如果我们记(x_i=sum_{j=1}^{i}f_{i,j}),那么递推式就是
这就是大家喜闻乐见的第一个递推式
但是我们现在要算(Ans=sum_{i=1}^{n}sum_{j=1}^{i}p_{i,j}j^3)
使用前面的补足思想,当(x=i+1)的时候,(x^3)需要对之前补足的贡献是((3i^2+3i+1))
因此
首先记(y_i=sum_{j=1}^{i}j^2p_{i,j}=sum_{j=1}^{i}[2 imes (j-1)+1]f_{i,j}),
由于(y_{i-1} imes p_i=sum_{j=1}^{i-1}[2 imes (j-1)+1]f_{i-1,j} imes p_i=sum_{j=2}^{i}[2 imes (j-2)+1]f_{i,j}),
故(y_i-y_{i-1} imes p_i=sum_{j=2}^{i}2f_{i,j}+f_{i,1}=2x_{i-1}p_i+p_i)
因此(y_i)的递推式为
这就是大家喜闻乐见的第二个递推式
这样我们可以推到次数为(3)的情况,
记(dis_i=sum_{j=1}^{i}p_{i,j}j^3=sum_{j=1}^{i}f_{i,j}(3j^2+3j+1)),
仿照(y_i)的方法我们有大家喜闻乐见的第三个递推式
使用这三个递推式即可解决问题
虽然这三个递推式并不好理解
但难道我们只是为了(AC)数而做题的吗?
#include<bits/stdc++.h>
using namespace std;
int n;dd a[N],x[N],y[N],dis[N];
int main()
{
n=read();
for(RG int i=1;i<=n;i++){
scanf("%lf",&a[i]);
x[i]=(x[i-1]+1)*a[i];
y[i]=(y[i-1]+2*x[i-1]+1)*a[i];
dis[i]=dis[i-1]+(3*y[i-1]+3*x[i-1]+1)*a[i];
}
printf("%.1lf
",dis[n]);
return 0;
}