Codeforces Round #674 (Div. 3) F. Number of Subsequences

    科技2022-07-11  111

    F. Number of Subsequences

    Description

    You are given a string s consisting of lowercase Latin letters “a”, “b” and “c” and question marks “?”.

    Let the number of question marks in the string s be k. Let’s replace each question mark with one of the letters “a”, “b” and “c”. Here we can obtain all 3k possible strings consisting only of letters “a”, “b” and “c”. For example, if s=“ac?b?c” then we can obtain the following strings: [“acabac”, “acabbc”, “acabcc”, “acbbac”, “acbbbc”, “acbbcc”, “accbac”, “accbbc”, “accbcc”].

    Your task is to count the total number of subsequences “abc” in all resulting strings. Since the answer can be very large, print it modulo 109+7.

    A subsequence of the string t is such a sequence that can be derived from the string t after removing some (possibly, zero) number of letters without changing the order of remaining letters. For example, the string “baacbc” contains two subsequences “abc” — a subsequence consisting of letters at positions (2,5,6) and a subsequence consisting of letters at positions (3,5,6).

    Input

    The first line of the input contains one integer n (3≤n≤200000) — the length of s.

    The second line of the input contains the string s of length n consisting of lowercase Latin letters “a”, “b” and “c” and question marks"?".

    Output

    Print the total number of subsequences “abc” in all strings you can obtain if you replace all question marks with letters “a”, “b” and “c”, modulo 109+7.

    Examples

    input
    6 ac?b?c
    outputCopy
    24
    input
    7 ???????
    output
    2835
    input
    9 cccbbbaaa
    output
    0
    input
    5 a???c
    output
    46

    Note

    In the first example, we can obtain 9 strings:

    “acabac” — there are 2 subsequences “abc”, “acabbc” — there are 4 subsequences “abc”, “acabcc” — there are 4 subsequences “abc”, “acbbac” — there are 2 subsequences “abc”, “acbbbc” — there are 3 subsequences “abc”, “acbbcc” — there are 4 subsequences “abc”, “accbac” — there is 1 subsequence “abc”, “accbbc” — there are 2 subsequences “abc”, “accbcc” — there are 2 subsequences “abc”. So, there are 2+4+4+2+3+4+1+2+2=24 subsequences “abc” in total.

    题意: 第一行输入一个数字n,第二行输入一串字符串,该串字符串只由a、b、c以及英文的“?”组成。"?" 可以变化成任意一个字母变成a、b、c其中的任意一个字母,现在要求在这个字符串中有多少个子串是“abc”,由?任意变化后的所有的子串。

    题解: 我们设一数组dp[i][1]代表前i个字符中子列’a‘的个数;dp[i][2]代表前i个字符中子列’ab‘的个数;dp[i][3]代表前i个字符中子列’abc‘的个数。那么最终答案一定是dp[n][3]。

    考虑‘?’对子列的影响,因为‘?‘可以代表a、b、c中任意一个字符,所有到了第i个字符时如果前面有x个’?’,那么此处可以组成的字符串的形式就有 3 x 3^x 3x种。如果不考虑‘?'的话,碰到一个’a‘,dp[i][1]就需要加一,如果考虑到’?'的影响,dp[i][1]就得加上 3 x 3^x 3x

    考虑用‘?'分别表示这三个字母:

    ’?‘代表‘a’:前面仍然有dp[i-1][1]个‘a’的子列,仍然有dp[i-1][2]个‘ab’的子列,仍然有dp[i-1][3]个‘abc’,算上第i个字符(即‘?’)这时候,多了 3 x 3^x 3x个a。

    ’?‘代表’b‘:前面仍然有dp[i-1][1]个‘a’的子列,仍然有dp[i-1][2]个‘ab’的子列,仍然有dp[i-1][3]个‘abc’,算上第i个字符(即‘?’)这时候,多了dp[i-1][1]个ab。

    ‘?‘代表’c’:前面仍然有dp[i-1][1]个‘a’的子列,仍然有dp[i-1][2]个‘ab’的子列,仍然有dp[i-1][3]个‘abc’,算上第i个字符(即‘?’)这时候,多了dp[i-1][2]个abc。

    通过上式状态转移方程,我们可以写出一下代码:

    c++ AC 代码

    #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int maxn = 2e5 + 10; ll dp[maxn][4]; ll base = 1; char s[maxn]; int main() { int n; scanf("%d%s",&n,s+1); for(int i=1;i<=n;i++) { if(s[i]=='a') { dp[i][1] = (dp[i-1][1] + base) % mod; dp[i][2] = dp[i-1][2]; dp[i][3] = dp[i-1][3]; } else if(s[i]=='b') { dp[i][1] = dp[i-1][1]; dp[i][2] = (dp[i-1][1] + dp[i-1][2]) % mod; dp[i][3] = dp[i-1][3]; } else if(s[i]=='c') { dp[i][1] = dp[i-1][1]; dp[i][2] = dp[i-1][2]; dp[i][3] = (dp[i-1][2] + dp[i-1][3]) % mod; } else if(s[i] == '?') { dp[i][1] = (dp[i-1][1] * 3 + base) % mod; dp[i][2] = (dp[i-1][2] * 3 + dp[i-1][1]) % mod; dp[i][3] = (dp[i-1][3] * 3 + dp[i-1][2]) % mod; base = base * 3 % mod; } } printf("%lld\n",dp[n][3]); // system("pause"); return 0; }

    文章参考自:https://blog.csdn.net/qq_45458915/article/details/108859787

    Processed: 0.009, SQL: 8