题目大意: 给出一个字符串,每个位置是 o
,x
,?
中的一个,如果是 ?
,表示这一位不确定是 o
还是 x
,各有
50
50
50% 的概率,对于一段长度为
p
p
p 的极长连续 o
,它的贡献为
p
2
p^2
p2,问期望总贡献。
题解
跟这题差不多的,背景居然也很像呢qwq
设
b
[
i
]
b[i]
b[i] 表示前
i
i
i 位的分数之和。假设在从
i
−
1
i-1
i−1 位开始往前有连续
X
X
X 个 o
,那么贡献就是
X
2
X^2
X2,假如第
i
i
i 位也是 o
,那么贡献变成
(
X
+
1
)
2
=
X
2
+
2
X
+
1
(X+1)^2=X^2+2X+1
(X+1)2=X2+2X+1,贡献多了
2
X
+
1
2X+1
2X+1。
为了求出
X
X
X,我们需要同时递推求出另一个数组
a
a
a,
a
[
i
]
a[i]
a[i] 表示从第
i
i
i 位开始往前期望有多少个连续的 o
。
下面考虑转移:
- 第
i
i
i 位是
o
: a [ i ] = a [ i − 1 ] + 1 a[i]=a[i-1]+1 a[i]=a[i−1]+1, b [ i ] = b [ i − 1 ] + 2 a [ i − 1 ] + 1 b[i]=b[i-1]+2a[i-1]+1 b[i]=b[i−1]+2a[i−1]+1 - 第
i
i
i 位是
x
: a [ i ] = 0 a[i]=0 a[i]=0, b [ i ] = b [ i − 1 ] b[i]=b[i-1] b[i]=b[i−1] - 第
i
i
i 位是
?
: a [ i ] = 1 2 ( a [ i − 1 ] + 1 ) a[i]=\frac 1 2(a[i-1]+1) a[i]=21(a[i−1]+1), b [ i ] = b [ i − 1 ] + 1 2 ( 2 a [ i − 1 ] + 1 ) b[i]=b[i-1]+\frac 1 2 (2a[i-1]+1) b[i]=b[i−1]+21(2a[i−1]+1)
第
3
3
3 种情况稍微解释一下:由于这一位不确定,如果是 x
的话
a
[
i
]
a[i]
a[i] 就是
0
0
0,否则是
a
[
i
−
1
]
+
1
a[i-1]+1
a[i−1]+1,各占
50
50
50% 几率,所以乘
1
2
\frac 1 2
21,后面的
b
[
i
]
b[i]
b[i] 类似,无论第
i
i
i 位是什么,前面
i
−
1
i-1
i−1 位的贡献是不会变的,所以先加上
b
[
i
−
1
]
b[i-1]
b[i−1],然后再看第
i
i
i 位的贡献,而第
i
i
i 位有
1
2
\frac 1 2
21 的概率提供新的贡献
2
a
[
i
−
1
]
+
1
2a[i-1]+1
2a[i−1]+1,还有
1
2
\frac 1 2
21 的概率没贡献,所以再加上
1
2
(
2
a
[
i
−
1
]
+
1
)
\frac 1 2(2a[i-1]+1)
21(2a[i−1]+1)。
代码如下:
#include <cstdio>
#define maxn 300010
int n;
char s[maxn];
double a[maxn],b[maxn];
int main()
{
scanf("%d %s",&n,s+1);
for(int i=1;i<=n;i++)
switch(s[i])
{
case 'x':a[i]=0;b[i]=b[i-1];break;
case 'o':a[i]=a[i-1]+1;b[i]=b[i-1]+2*a[i-1]+1;break;
case '?':a[i]=0.5*a[i-1]+0.5;b[i]=b[i-1]+a[i-1]+0.5;break;
}
printf("%.4lf",b[n]);
}