1. 程式人生 > 其它 >2021中國大學生程式設計競賽(CCPC)- 網路選拔賽(重賽)

2021中國大學生程式設計競賽(CCPC)- 網路選拔賽(重賽)

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;
}