dp[i]表示前i个字母里面一定有连续k个’B’的情况总数
dp1[i]表示前i个字母里面只有第i号位置出现有连续k个’B’情况总数
然后答案的话就是直接枚举第一次出现连续k个’B’的位置,
然后情况总数*后面一定出现连续k个’W’情况总数
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e6+100;
const int mod=1e9+7;
typedef __int64 LL;
LL mi[N];
void init(){
int n=1e6;
mi[0]=1;
for(int i=1;i<=n;i++){
mi[i]=mi[i-1]*2%mod;
}
}
char ss[N];
int n,k;
int cnt[N][3];
int getid(char ch){
if(ch=='B')return 0;
if(ch=='W')return 1;
return 2;
}
int getnum(int l,int r){
if(l)return cnt[r][1]-cnt[l-1][1];
else return cnt[r][1];
}
void getdp(LL dp[N],LL dp1[N]){
//printf("%s\n",ss);
for(int i=0;i<n;i++){
if(i){
for(int j=0;j<3;j++)cnt[i][j]=cnt[i-1][j];
}
else {
for(int j=0;j<3;j++)cnt[i][j]=0;
}
cnt[i][getid(ss[i])]++;
if(i){
if(ss[i]=='X')dp[i]=dp[i-1]*2%mod;
else dp[i]=dp[i-1];
}
else {
dp[i]=0;
}
dp1[i]=0;
if(i==k-1){
int num=getnum(i-k+1,i);
if(!num){
dp1[i]=1;
}
}
else if(i==k){
int num=getnum(i-k+1,i);
if(!num&&ss[i-k]!='B'){
dp1[i]=1;
}
}
else if(i>k){
int num=getnum(i-k+1,i);
if(!num&&ss[i-k]!='B'){
dp1[i]=(mi[cnt[i-k-1][2]]-dp[i-k-1]+mod)%mod;
}
}
dp[i]=(dp[i]+dp1[i])%mod;
}
}
LL dp[2][N],dp1[2][N];
int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
init();
while(scanf("%d%d",&n,&k)!=EOF){
scanf("%s",ss);
getdp(dp[0],dp1[0]);
// for(int i=0;i<n;i++){
// printf("%d %I64d %I64d\n",i,dp[0][i],dp1[0][i]);
// }
for(int i=0;i<n;i++){
if(ss[i]=='B'){
ss[i]='W';
}
else if(ss[i]=='W'){
ss[i]='B';
}
}
for(int i=0;i<n/2;i++){
swap(ss[i],ss[n-1-i]);
}
getdp(dp[1],dp1[1]);
// for(int i=0;i<n;i++){
// printf("%d %I64d %I64d\n",i,dp[1][i],dp1[1][i]);
// }
int ans=0;
for(int i=0;i<n-1;i++){
ans+=dp1[0][i]*dp[1][n-1-(i+1)]%mod;
ans%=mod;
}
printf("%d\n",ans);
}
return 0;
}