2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛)

Nun Heh Heh Aaaaaaaaaaa

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 262144/262144 K (Java/Others)

Problem Description

Vasily Tadokorov is a stringologist. He thinks a string is fragrant if it can be divided into two parts — nunhehheh as the prefix and a number of (excluding 0) a as the suffix. For example, nunhehhehaaaaaa is fragrant, but nunhehheh and nunhehhehoooaaa are not fragrant.

Today Vasily Tadokorov has some strings consisting of lowercase English letters. For each string, he wants to know how many subsequences of this string are fragrant. A string a is a subsequence of a string b if a can be obtained from b by deletion of several (including 0) characters.

Input

The first line contains an integer \(T (1≤T≤1000)\), denoting the number of strings.

Each of the next T lines contains a string \(S (1≤|S|≤10^5)\) consisting of lowercase English letters.

The total length of the strings in the input will not exceed \(10^6\).

Output

For each of the given \(T\) strings, output the answer modulo \(998244353\).

Sample Input

2
nunhehhehahaahahahahahahaahaahahahahha
nunhehhehhehhahaahahahaahaahahaaaahaa

Sample Output

114514
1919810

解题思路

dp

先考虑这样一问题:子序列 \(p\) 在母串 \(s\) 中出现的次数?

  • 状态表示:\(f(i,j)\) 表示子序列的前 \(j\) 个字符在母串 \(s\) 的前 \(i\) 个字符出现的次数
  • 状态计算:
    • \(f[i][1]=f[i-1][1]+(s[i]==p[1])\)
    • \(f[i][j]=f[i-1][j]+(s[i]==p[j])*f[i-1][j-1]\)
      分析:\(f[i][1]\) 容易得到转移方程;\(j>1\) 时,当 \(s[i] \neq p[j]\),显然,\(f[i][j]=f[i-1][j]\),否则以子序列的第 \(j\) 个字符作为分界点,可分为两种情况:1.子序列的前 \(j\) 个字符在母串的前 \(i-1\) 出现的次数,即不考虑母串的第 \(i\) 个字符造成的影响。2.考虑母串的第 \(i\) 个字符造成的影响时,等价于子序列的前 \(j-1\) 个字符在母串的前 \(i-1\) 出现的次数

每次维护答案增加的次数,即每两个a之间子序列nunhehheh出现的次数乘以后面a数量的方案数

  • 时间复杂度:\(O(9\times n\times T)\)

代码

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
string p=" nunhehheh";
long long f[12];
int mx[100005];
char s[100005];
long long ksm(int a,int b)
{
    long long res=1%mod;
    for(;b;b>>=1)
    {
        if(b&1)res=(res*a)%mod;
        a=1ll*a*a%mod;
    }
    return res;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s+1);
        int len=strlen(s+1);
        long long res=0;
        memset(f,0,sizeof f);
        memset(mx,0,sizeof mx);
        long long last=0;
        for(int i=len;i>=1;i--)
            mx[i]=mx[i+1]+(s[i]=='a');
        for(int i=1;i<=len;i++)
        {
            for(int j=9;j>1;j--)
            {
                f[j]=(f[j]+(s[i]==p[j])*f[j-1])%mod;
            }
            f[1]=(f[1]+(s[i]==p[1]))%mod;
            if(s[i]=='a')res=(res+(f[9]-last+mod)%mod*(ksm(2,mx[i])-1+mod)%mod)%mod,last=f[9]%mod;
        }
        printf("%lld\n",res);
    }
    return 0;
}
posted @ 2021-10-10 20:34  zyy2001  阅读(694)  评论(0编辑  收藏  举报