Description
给定一个串,包含字符 a
,b
,c
,?
,其中 ?
代表通配符,即这个位置可以是任意一个字符。求所有能与这个串匹配的确定串中,子序列 abc
的数量之和。
Solution
设 (f[i][j]) 表示对于 (s[1..i]),包含子序列 a
,ab
,abc
的数量之和各为多少,则对于 (s[i]
eq ?),有
(f[i][1] = f[i-1][1] + (s[i]==a) cdot 3^{cnt}, f[i][2] = f[i-1][1] + (s[i]==b) cdot f[i-1][1], f[i][3] = f[i-1][3] + (s[i]==c) cdot f[i-1][2])
对于 (s[i] = ?),则
(f[i][1] = 3f[i-1][1] + 3^{cnt}, f[i][2] = 3f[i-1][1] + f[i-1][1], f[i][3] = 3f[i-1][3] + f[i-1][2])
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
int qpow(int p,int q)
{
return (q&1 ? p:1) * (q?qpow(p*p%mod,q/2):1) % mod;
}
int n;
string s;
int f[N][4];
signed main()
{
ios::sync_with_stdio(false);
cin>>n;
cin>>s;
int cnt=0;
for(int i=1;i<=n;i++)
{
char c=s[i-1];
if(c=='?')
{
f[i][1]=3*f[i-1][1]+qpow(3,cnt);
f[i][2]=3*f[i-1][2]+f[i-1][1];
f[i][3]=3*f[i-1][3]+f[i-1][2];
}
else
{
f[i][1]=f[i-1][1]+(c=='a')*qpow(3,cnt);
f[i][2]=f[i-1][2]+(c=='b')*f[i-1][1];
f[i][3]=f[i-1][3]+(c=='c')*f[i-1][2];
}
for(int j=1;j<=3;j++) f[i][j]%=mod;
if(c=='?') ++cnt;
}
cout<<f[n][3]<<endl;
}