1006

摘要:后缀 快速幂 DP

如何计算字符串中特定子序列的个数?

利用关系

\[dp[j][i]=dp[j][i-1]+dp[j-1][i-1]*(s[i]==as[j]) \]

\(dp[j][i]\)指文本串前 \(i\) 个字符中"\(nunhehheh\)"的个数,复杂度为 \(O(MN)\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
ll dp[11][101000];//count the string ss
int ca[100010];//count a
ll qp(ll base,ll pw){
    ll ans=1;
    while (pw)
    {
        if(pw&1)
            ans=(ans*base)%mod;
        base=(base*base)%mod;
        pw>>=1;
    }
    return ans;
}

int main(){
    int T;
    cin>>T;
    string as="0nunhehheh";
    while (T--)
    {
        memset(ca,0,sizeof(ca));
        memset(dp,0,sizeof(dp));
        string s;cin>>s;
        s='0'+s;
        ll ans=0;
        int lent=s.size();
        // int cnt=0;
        for(int i=lent-1;i>=1;i--)
            ca[i]=ca[i+1]+(s[i]=='a');
        for(int i=0;i<100010;i++)
            dp[0][i]=1;
        for (int i = 1; i <= lent; i++)
        {
            for(int j=1;j<=as.size()-1;j++)
                dp[j][i]=(dp[j][i-1]+dp[j-1][i-1]*(s[i]==as[j]))%mod;
            dp[9][i]=(dp[8][i-1]*(s[i]==as[9]))%mod;
            if(dp[9][i])
                ans=(ans%mod+(qp(2,ca[i])-1)*dp[9][i])%mod;    
        }
        cout<<ans<<'\n';
    }

    system("pause");
    return 0;
}
 posted on 2021-10-13 20:21  Stuart_Assassins  阅读(27)  评论(0)    收藏  举报