题目大意:
给定一个字符串包含a,b,c,?
?可以转变为a,b,c中的一个,问模1e9+7意义下子序列a,b,c的个数
input:6ac?b?coutput:24input:7???????output:2835
abc序列个数可以与ab序列的个数相关,ab序列的个数又与包含a字符的字符串个数相关
遍历字符串,若当前字符为c,对答案的贡献为前面ab序列的个数
若当前字符为b,对ab序列的个数的贡献为前面a的个数
若当前字符为a,记前面q的个数为qcnt,对a个数的贡献为pow(3,qcnt)
若当前字符为?
对答案的贡献为ans = ans * 3 + 前面ab序列的个数
对a个数的贡献为前面a的个数 * 3 + pow(3,qcnt)
对ab序列的贡献为前面ab序列的个数 * 3 + 前面a的个数
#include<iostream>
using namespace std;
const int N = 2e5 + 5;
const int mod = 1e9 + 7;
typedef long long ll;
ll dp_a[N],dp_ab[N],ans;
char s[N];
ll fast_pow(ll a,ll b){
ll ans = 1;while(b){
if(b&1)ans = (ans * a)% mod;a = (a * a) %mod;b>>=1;}return ans;
}
ll qcnt = 0;
int n;
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n;cin>>(s + 1);for(int i = 1;i <= n;i++){
if(s[i] == 'a'){
dp_ab[i] = dp_ab[i - 1];dp_a[i] = (dp_a[i - 1] + fast_pow(3,qcnt)) % mod;}else if(s[i] == 'b'){
dp_ab[i] = (dp_ab[i - 1] + dp_a[i - 1]) % mod;dp_a[i] = dp_a[i - 1];}else if(s[i] == 'c'){
ans = (ans + dp_ab[i - 1]) % mod;dp_a[i] = dp_a[i - 1];dp_ab[i] = dp_ab[i - 1];}else if(s[i] == '?'){
dp_ab[i] = ((dp_ab[i - 1] * 3)% mod + dp_a[i - 1]) % mod;dp_a[i] = ((dp_a[i - 1] * 3)%mod + fast_pow(3,qcnt)) % mod;ans = (ans * 3 % mod + dp_ab[i - 1]) % mod;qcnt++;}}cout<<ans; return 0;
}