[BZOJ] OSU!

题目

BZOJ链接......它死了。

点这里看题目。

分析

感觉是期望入门的优质题目。

首先我们需要明确:幂的期望不等于期望的幂

显然可以利用期望的线性性质将答案拆分成每一段的期望。

于是可以定义一个离散随机变量 \(X_i\) :前 \(i\) 次操作后,成功操作的极长后缀的长度

不妨设第 \(i\) 次操作成功的概率为 \(p_i\), 然后有:

\[X_i= \begin{cases} X_{i-1}+1 & p_i\\ 0 & 1-p_i \end{cases} \]

对它求一下期望:

\[E(X_i)=p_iE(X_{i-1}+1)+(1-p_i)E(0)=p_iE(X_{i-1})+p_i \]

注意对 \(X_{i-1}\) 也需要套一个期望,因为它是随机变量,已经囊括了很多取值;而期望应该是定值。

然后考虑幂的情况。由于幂的推导之间有相似之处,这里只选取平方分析。

\[X_i^2= \begin{cases} (X_{i-1}+1)^2 & p_i\\ 0^2 & 1-p_i \end{cases} \]

然后同理可以得到:

\[E(X_i^2)=p_i(E(X_{i-1}^2)+2E(X_{i-1})+1) \]

我们再同理一下推导一下可以得到:

\[E(X_i^3)=p_i(E(X_{i-1}^3)+3E(X_{i-1}^2)+3E(X_{i-1})+1) \]

然后就可以 \(O(n)\) 维护幂的期望。

最后考虑答案。不难发现,我们应该在一段极长的成功操作被打断之后将它加入答案。也就是说:

\[ans=\sum_{i=1}^n(1-p_{i+1})E(X_i^3) \]

假定 \(p_{n+1}=0\) ,也就是最后一段必然会断掉。

总时间是 \(O(n)\)

代码

#include <cstdio>

const int MAXN = 1e5 + 5;

template<typename _T>
void read( _T &x )
{
	x = 0;char s = getchar();int f = 1;
	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
	x *= f;
}

template<typename _T>
void write( _T x )
{
	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
	if( 9 < x ){ write( x / 10 ); }
	putchar( x % 10 + '0' );
}

double E1[MAXN], E2[MAXN], E3[MAXN];
double p[MAXN];
int N;

int main()
{
	read( N );
	for( int i = 1 ; i <= N ; i ++ )
		scanf( "%lf", &p[i] );
	double ans = 0;
	for( int i = 1 ; i <= N ; i ++ )
	{
		E1[i] = p[i] * ( E1[i - 1] + 1 );
		E2[i] = p[i] * ( E2[i - 1] + 2 * E1[i - 1] + 1 );
		E3[i] = p[i] * ( E3[i - 1] + 3 * E2[i - 1] + 3 * E1[i - 1] + 1 );
		ans += E3[i] * ( 1 - p[i + 1] );
	}
	printf( "%.1lf\n", ans );
	return 0;
}
posted @ 2020-07-29 11:26  crashed  阅读(189)  评论(0编辑  收藏  举报