首先我们设置
d
p
i
,
0
/
1
,
0
/
1
dp_{i,0/1,0/1}
dpi,0/1,0/1表示经过
i
i
i次操作之后开头为
r
e
d
/
e
d
r
red/edr
red/edr,结尾为
r
e
d
/
e
d
r
red/edr
red/edr的串的期望
r
e
d
red
red字符串个数。
然后我们考虑转移:
首先我们要来思考一下期望的本质,这样一个状态,我们以
d
p
i
,
0
,
0
dp_{i,0,0}
dpi,0,0为例,里面可能有很多种情况,比如串
"
r
e
d
r
e
d
"
"redred"
"redred"和串
"
r
e
d
e
d
r
r
e
d
"
"rededrred"
"rededrred"每一种有一个概率和贡献,假设有
n
n
n种情况,每一种的概率是
p
i
p_i
pi,贡献是
X
i
X_i
Xi,那么
d
p
i
,
0
,
0
=
∑
i
=
1
p
i
X
i
dp_{i,0,0}=\sum_{i=1}p_iX_i
dpi,0,0=i=1∑piXi
那么我们考虑在这个状态后面接上一个
"
r
e
d
"
"red"
"red"串,也就是第一种操作,这里面的串的概率和贡献会如何变化呢?
对于上述的一个状态
p
i
X
i
p_iX_i
piXi,加上一个
"
r
e
d
"
"red"
"red"串之后贡献
X
i
X_i
Xi变为
X
i
+
1
X_i+1
Xi+1,概率
P
i
P_i
Pi变为
P
i
3
\frac{P_i}{3}
3Pi所以这样一种转移让
d
p
i
+
1
,
0
,
0
+
=
∑
i
=
1
p
i
3
(
X
i
+
1
)
=
∑
i
=
1
p
i
X
i
3
+
∑
i
=
1
p
i
3
dp_{i+1,0,0}+=\sum_{i=1}\frac{p_i} {3} (X_i+1)=\sum_{i=1}\frac{p_iX_i} {3}+\sum_{i=1}\frac{p_i} {3}
dpi+1,0,0+=i=1∑3pi(Xi+1)=i=1∑3piXi+i=1∑3pi
所以我们再记录一个
p
i
,
0
/
1
,
0
/
1
p_{i,0/1,0/1}
pi,0/1,0/1表示经过
i
i
i次操作之后开头为
r
e
d
/
e
d
r
red/edr
red/edr,结尾为
r
e
d
/
e
d
r
red/edr
red/edr的串的概率,即可转移。
第二种操作和第三种操作同理可以得到:
对于四种情况各自分类讨论即可。但值得注意的是空串不在我们的考虑范围内,得提出来单独计算。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll poww(ll a,ll b){
ll t=1;
while(b){
if(b&1)t=t*a%mod;
a=a*a%mod;
b>>=1;
}
return t;
}
void add(int &a,int b){
a+=b;
if(a>=mod)a-=mod;
}
void del(int &a,int b){
a-=b;
if(a<0)a+=mod;
}
const int M=2e5+50;
int dp[M][2][2];
int P[M][2][2];
int main()
{
int k;
scanf("%d",&k);
//P[0][0][0]=1;
int inv3=poww(3,mod-2);
int P0=1;
for(int i=0;i<k;i++){
//printf("%d %d %d %d\n",P[i][0][0],P[i][0][1],P[i][1][0],P[i][1][1]);
{
add(dp[i+1][0][0],1ll*P0*inv3%mod);
add(P[i+1][0][0],1ll*P0*inv3%mod);
if(i>=1){
add(dp[i+1][1][0],1ll*inv3*P0%mod);
add(P[i+1][1][0],1ll*P0*inv3%mod);
add(dp[i+1][1][1],1ll*inv3*P0%mod);
add(P[i+1][1][1],1ll*P0*inv3%mod);
add(dp[i+1][1][1],1ll*9*inv3%mod*P0%mod);
add(P[i+1][1][1],1ll*P0*inv3%mod);
}
P0=1ll*P0*inv3%mod;
}
// red...red
add(dp[i+1][0][0],((1ll*dp[i][0][0]*inv3%mod)+1ll*P[i][0][0]*inv3%mod)%mod);
add(P[i+1][0][0],1ll*P[i][0][0]*inv3%mod);
add(dp[i+1][0][1],1ll*dp[i][0][0]%mod*inv3%mod);
add(P[i+1][0][1],1ll*P[i][0][0]*inv3%mod);
add(dp[i+1][0][0],10ll*dp[i][0][0]%mod*inv3%mod);
add(P[i+1][0][0],1ll*P[i][0][0]*inv3%mod);
// red..edr dp[0][1]
add(dp[i+1][0][0],((1ll*dp[i][0][1]*inv3%mod)+1ll*P[i][0][1]*inv3%mod)%mod);
add(P[i+1][0][0],1ll*P[i][0][1]*inv3%mod);
add(dp[i+1][0][1],((1ll*dp[i][0][1]*inv3%mod)+1ll*P[i][0][1]*inv3%mod)%mod);
add(P[i+1][0][1],1ll*P[i][0][1]*inv3%mod);
add(dp[i+1][0][1],(1ll*(10ll*dp[i][0][1])%mod*inv3%mod));
add(P[i+1][0][1],1ll*P[i][0][1]*inv3%mod);
// edr red dp[1][0]
add(dp[i+1][1][0],((1ll*dp[i][1][0]*inv3%mod)+1ll*P[i][1][0]*inv3%mod)%mod);
add(P[i+1][1][0],1ll*P[i][1][0]*inv3%mod);
add(dp[i+1][1][1],1ll*(dp[i][1][0])*inv3%mod);
add(P[i+1][1][1],1ll*P[i][1][0]*inv3%mod);
add(dp[i+1][1][0],1ll*(10ll*dp[i][1][0])%mod*inv3%mod);
add(P[i+1][1][0],1ll*P[i][1][0]*inv3%mod);
// edr edr dp[1][1]
add(dp[i+1][1][0],((1ll*dp[i][1][1]*inv3%mod)+1ll*P[i][1][1]*inv3%mod)%mod);
add(P[i+1][1][0],1ll*P[i][1][1]*inv3%mod);
add(dp[i+1][1][1],((1ll*dp[i][1][1]*inv3%mod)+1ll*P[i][1][1]*inv3%mod)%mod);
add(P[i+1][1][1],1ll*P[i][1][1]*inv3%mod);
add(dp[i+1][1][1],((10ll*dp[i][1][1]%mod*inv3%mod)+9ll*P[i][1][1]%mod*inv3%mod)%mod);
add(P[i+1][1][1],1ll*P[i][1][1]*inv3%mod);
}
int ans=0;
add(ans,dp[k][0][0]);
add(ans,dp[k][0][1]);
add(ans,dp[k][1][0]);
add(ans,dp[k][1][1]);
printf("%d",ans);
return 0;
}