把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【洛谷1654】OSU!(期望)

点此看题面

  • 有一个长度为\(n\)的序列,其中第\(i\)个位置有\(a_i\)的概率为\(1\)
  • 问所有极长的连续的\(1\)的长度立方和的期望。
  • \(n\le10^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\n",S+C),0;//输出答案时要算上最后一个连续段
}
posted @ 2020-10-28 12:45  TheLostWeak  阅读(155)  评论(0编辑  收藏  举报