当前位置: 代码迷 >> 综合 >> codeforcs round 674[字符串dp]F. Number of Subsequences
  详细解决方案

codeforcs round 674[字符串dp]F. Number of Subsequences

热度:44   发布时间:2024-02-25 14:24:00.0

题目大意:
给定一个字符串包含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;
}
  相关解决方案