【洛谷1654】OSU!(期望)

点此看题面

  • 有一个长度为(n)的序列,其中第(i)个位置有(a_i)的概率为(1)
  • 问所有极长的连续的(1)的长度立方和的期望。
  • (nle10^5)

期望

立方的期望显然不等于期望的立方,这种东西自己举几个例子就知道了。

考虑我们维护到第(i)个位置为止的答案为(ans_i),连续长度期望为(A_i),连续长度平方期望为(B_i),连续长度立方期望为(C_i)

一次期望的长度转移是显然的:

[A_i=a_i(A_{i-1}+1) ]

对于二次期望,考虑((x+1)^2=x^2+2x+1),可以借助一次期望一同计算:

[B_i=a_i(B_{i-1}+2A_{i-1}+1) ]

知道二次期望,三次期望就同理了:

[C_i=a_i(C_{i-1}+3B_{i-1}+3A_{i-1}+1) ]

至于答案,由于它求的是极长连续段,所以我们有:(只有不连续了才能算答案)

[ans_i=ans_{i-1}+(1-a_i)C_{i-1} ]

但注意这样没有计算最后一个连续段,因此最终的答案为(ans_n+C_n)

具体实现时没必要开数组。

代码:(O(n))

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define DB double
using namespace std;
int n;
int main()
{
	RI i;DB x,A=0,B=0,C=0,S=0;for(scanf("%d",&n),i=1;i<=n;++i)
		scanf("%lf",&x),S+=(1-x)*C,C=x*(C+3*B+3*A+1),B=x*(B+2*A+1),A=x*(A+1);//注意转移的先后顺序
	return printf("%.1lf
",S+C),0;//输出答案时要算上最后一个连续段
}
原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu1654.html