期望分数【ybtoj高效进阶6-6-2】
WJMZBMR打osu! / Easy 【luogu P1365】
题目描述:
给定一个长度为n的由 o,x,? 组成的字符串。计算分数的规则如下:连续 a 个 o 可以得到 a 2 a^2 a2分。对于 ? 的地方,有50%的概率为 o ,另外50%的概率为x,求该字符串的期望分数。
思路:
首先,设
t
o
p
top
top 为此时连续
o
o
o 串的最大长度。
如果当前位置
i
i
i ,第
i
−
1
i-1
i−1 位时连续
o
o
o 串的长度是
t
o
p
top
top ,
s
[
i
]
=
o
s[i]=o
s[i]=o,那么相应的,我们有
a
n
s
+
=
(
2
∗
t
o
p
+
1
)
ans+=(2*top+1)
ans+=(2∗top+1)
t
o
p
+
+
top++
top++
为什么
2
∗
t
o
p
+
1
2*top+1
2∗top+1呢?
因为对于每一个是o的s[i]它对答案的贡献是
(
t
o
p
+
1
)
2
−
t
o
p
2
=
2
∗
t
o
p
+
1
(top+1)^2-top^2=2*top+1
(top+1)2−top2=2∗top+1
那么当
s
[
i
]
=
x
s[i]=x
s[i]=x使,top清零,连续o串长度变成0(显而易见)
当
s
[
i
]
=
?
s[i]=?
s[i]=?时 那就全部乘上0.5
a
n
s
+
=
(
2
∗
t
o
p
+
1
)
/
2.0
ans+=(2*top+1)/2.0
ans+=(2∗top+1)/2.0
t
o
p
=
(
t
o
p
+
1
)
/
2.0
top=(top+1)/2.0
top=(top+1)/2.0
然后放上代码:
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
const ll V=1e7+10;
ll n;
double ans,top;
string s;
int main()
{
scanf("%lld",&n);
cin>>s;
rep(i,0,n-1)
{
if(s[i]=='o')
{
++top;
ans+=(double)(top*top-(top-1)*(top-1));
}
else if(s[i]=='x') top=0;
else
{
ans+=(double)(top*2+1.0)/2.0;
top=(top+1.0)/2.0;
}
}
printf("%.4lf",ans);
return 0;
}