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|≤105) consisting of lowercase English letters.
The total length of the strings in the input will not exceed 106.
Output
For each of the given T strings, output the answer modulo 998244353.
题解
dp[j][i] 表示s串中0 ~ i - 1中 子序列为 nunhehheh的0 ~ j - 1的个数,对于当前位置i求得新增加的子序列个数 (dp[9][i] - dp[9][i]) * i后面a的排列组合(2^(pre[s.size()] - pre[i]) - 1, (pre[s.size()] - pre[i])个 'a’每个选或者不选的方案 - 都不选的方案)
注意dp状态转移过程会爆long long 要边转移边取模,差值也要取模如
( dp[9][i] - dp[9][i - 1] + mod )%mod;,比赛的时候因为忘了这个wa惨了
code
#include <bits/stdc++.h>
using namespace std;
#define IOS std::ios_base::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
typedef long long ll;
ll mod = 998244353;
ll qq(ll b){
ll ans = 1;
ll a = 2;
while(b > 0){
if(b&1){
ans = (ans * a) % mod;
}
a = (a * a)%mod;
b >>= 1;
}
return ans;
}
string s,t = "nunhehheh";
const int N = 1E5 + 10;
ll dp[11][N];
ll pre[N];
int main()
{
IOS
int T; cin >> T;
for(int k = 1; k <= T; ++k){
cin >> s;
int sz = s.size(),tz = t.size();
for(int i = 1; i <= sz; ++i){
pre[i] = 0;
if(s[i-1] == 'a')
pre[i] = 1;
pre[i] += pre[i - 1];
}
ll ans = 0;
memset(dp,0,sizeof dp);
for(int i = 0; i <= sz; ++i)
dp[0][i] = 1;
for(int i = 1; i <= sz; ++i)
{
for(int j = 1; j <= tz; ++j)
{
/* 根据是否相等执行不同操作,因为此时需要匹配t[0 : j],而只有相等是才可以允许只匹配t[0 : j-1] */
if(s[i - 1] == t[j - 1])
dp[j][i] = (dp[j - 1][i - 1] + dp[j][i-1])%mod;
else
dp[j][i] = dp[j][i-1];
}
ll x = pre[sz] - pre[i];
ll y = ( dp[tz][i] - dp[tz][i - 1] + mod )%mod;
y%=mod;
if( y && x){
y = y * ( ( qq(x) - 1 + mod )%mod ) % mod;
ans += y;
ans %= mod;
}
}
cout << ans << '\n';
}
return 0;
}