设
g
l
,
r
,
c
∈
0
/
1
,
d
∈
0
/
1
g_{l,r,c\in 0/1,d\in 0/1}
gl,r,c∈0/1,d∈0/1表示对于小
R
R
R , 在第
l
−
1
l-1
l−1场比赛的输赢情况是
c
c
c,在第
r
+
1
r+1
r+1场比赛的输赢情况是
d
d
d之下的
[
l
,
r
]
[l,r]
[l,r]中的胜利期望场数,
f
l
,
r
,
c
,
d
f_{l,r,c,d}
fl,r,c,d是在第
l
−
1
l-1
l−1场比赛的输赢情况是
c
c
c,在第
r
+
1
r+1
r+1场比赛的输赢情况是
d
d
d的概率。
f
a
,
b
,
c
,
d
=
f
a
,
k
,
c
,
e
∗
f
k
+
1
,
b
,
e
,
d
f_{a,b,c,d} = f_{a,k,c,e} * f_{k+1,b,e,d}
fa,b,c,d=fa,k,c,e∗fk+1,b,e,d
g
a
,
b
,
c
,
d
=
f
a
,
k
,
c
,
e
∗
g
k
+
1
,
b
,
e
,
d
+
g
a
,
k
,
c
,
e
∗
f
k
+
1
,
b
,
e
,
d
g_{a,b,c,d} = f_{a,k,c,e} * g_{k+1,b,e,d} + g_{a,k,c,e} * f_{k+1,b,e,d}
ga,b,c,d=fa,k,c,e∗gk+1,b,e,d+ga,k,c,e∗fk+1,b,e,d
可以发现对于后两维,这就是一个
2
×
2
2 \times 2
2×2矩阵的乘法。(这不重要,重要的是结合律)
所以我们就可以算了。
修改?可以很简单的计算。
至于网上的贝叶斯公式,就是对于
f
,
g
f,g
f,g计算的理论依据。
A
C
C
o
d
e
\rm AC \ Code
AC Code
#include<bits/stdc++.h>
#define maxn 200005
#define lim 18
using namespace std;
struct mat{
double a[2][2];
mat(double d=0){ a[0][1]=a[1][0]=0,a[0][0]=a[1][1]=d; }
mat operator *(const mat &B)const{
mat r;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
r.a[i][k] += a[i][j] * B.a[j][k];
return r;
}
mat operator +(const mat &B)const{
mat r;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
r.a[i][j] = a[i][j] + B.a[i][j];
return r;
}
}f[lim][maxn],s[lim][maxn];
int S[maxn];
set<int>st;
double ask(int l,int r){
mat t(1),g;int L=l;
for(int i=lim-1;i>=0;i--)
if(l+(1<<i)-1 <= r){
g = t * s[i][l] + g * f[i][l];
t = t * f[i][l];
l += (1<<i);
}
if(S[r] == -1) return (g.a[S[L-1]][0] + g.a[S[L-1]][1]) / (t.a[S[L-1]][0] + t.a[S[L-1]][1]);
return g.a[S[L-1]][S[r]] / t.a[S[L-1]][S[r]];
}
int n,m;
int main(){
freopen("1.in","r",stdin);
char typ[10];scanf("%d%d%s",&n,&m,typ);
scanf("%lf",&f[0][1].a[1][1]);f[0][1].a[1][0]=1-f[0][1].a[1][1],s[0][1].a[1][1]=f[0][1].a[1][1];
for(int i=2;i<=n;i++)
scanf("%lf%lf",&f[0][i].a[1][1],&f[0][i].a[0][1]),
f[0][i].a[1][0] =1-f[0][i].a[1][1], f[0][i].a[0][0] =1-f[0][i].a[0][1],
s[0][i].a[1][1] = f[0][i].a[1][1] , s[0][i].a[0][1] = f[0][i].a[0][1];
for(int j=1;j<lim;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
f[j][i] = f[j-1][i] * f[j-1][i+(1<<j-1)] ,
s[j][i] = s[j-1][i] * f[j-1][i+(1<<j-1)] + f[j-1][i] * s[j-1][i+(1<<j-1)];
st.insert(0),st.insert(n);
memset(S,-1,sizeof S) , S[0] = 1;
double ans = ask(1,n);
for(int i,c;m--;){
scanf("%s",typ);
if(typ[0] == 'a'){
scanf("%d%d",&i,&c);
set<int>::iterator r = st.lower_bound(i) , l = r; l--;
ans -= ask(*l+1,*r);
S[i] = c;
ans += ask(*l+1,i) + ask(i+1,*r);
st.insert(i);
}
else{
scanf("%d",&i);
if(i != n) st.erase(i);
set<int>::iterator r = st.lower_bound(i) , l = r ; l--;
ans -= ask(*l+1,i) + ask(i+1,*r);
S[i] = -1;
ans += ask(*l+1,*r);
}
printf("%.6lf\n",ans);
}
}