洛谷P5404 [CTS2019] 重复

先转化为总方案数减去每个子串都大于等于 S 的方案数。

T 为所统计的字符串。对 S 构建 kmp 自动机,自动机上的每个节点只保留转移到根节点和转移到 next 链上字符最大的节点两种转移路径,因为如果 T 在匹配时不走最大的字符,T 在重复后,一定会出现小于 S 的子串。

pT 重复无限次后对应的节点,那么节点 p 一定满足再加入一个 T 后,其又回到了节点 p,即出现了一个环,该环可能重复经过节点。

那么考虑 DP,统计自动机上一个节点走 m 步后回到其本身的方案数,复杂度为 O(n2m),要考虑优化。

发现环可以分为经过根节点和不经过根节点的两种。不经过根节点可以直接判断,经过根节点可以枚举起始节点和第一次转移到根节点前走的距离,预处理出 fi,x,为从根节点走了 i 步到节点 x 的方案数,通过预处理的信息即可统计答案。

统计答案时可以快速算出第一次转移到根节点前的方案数,因为自动机一直不经过根节点前走的路径是唯一的,即一直匹配。

复杂度为 O(nm)

#include<bits/stdc++.h>
#define maxn 2010
#define p 998244353
using namespace std;
typedef long long ll;
template<typename T> inline void read(T &x)
{
    x=0;char c=getchar();bool flag=false;
    while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    if(flag)x=-x;
}
int m,n,pos;
ll tot=1,ans;
int nxt[maxn],mx[maxn],ch[maxn][30];
ll f[maxn][maxn];
char s[maxn];
int main()
{
    read(m),scanf("%s",s+1),n=strlen(s+1);
    for(int i=2;i<=n;++i)
    {
        while(pos&&s[i]!=s[pos+1]) pos=nxt[pos];
        if(s[i]==s[pos+1]) pos++;
        nxt[i]=pos;
    }
    for(int x=0;x<=n;++x)
    {
        mx[x]=max(mx[nxt[x]],s[x+1]-'a');
        for(int i=0;i<mx[x];++i) ch[x][i]=-1;
        for(int i=mx[x];i<26;++i)
        {
            if(s[x+1]-'a'==i) ch[x][i]=x+1;
            else
            {
                int y=nxt[x];
                while(ch[y][i]==-1) y=nxt[y];
                ch[x][i]=ch[y][i];
            }
        }
    }
    f[0][0]=1;
    for(int i=0;i<m;++i)
    {
        tot=tot*26%p;
        for(int x=0;x<=n;++x)
        {
            if(!f[i][x]) continue;
            for(int c=mx[x];c<26;++c)
                f[i+1][ch[x][c]]=(f[i+1][ch[x][c]]+f[i][x])%p;
        }
    }
    for(int x=0;x<=n;++x)
    {
        int y=x;
        for(int i=0;i<m;++i)
            ans=(ans+(25-mx[y])*f[m-i-1][x]%p)%p,y=ch[y][mx[y]];
        if(y==x) ans++;
    }
    printf("%lld",(tot-ans+p)%p);
    return 0;
}
posted @   lhm_liu  阅读(221)  评论(1编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥
点击右上角即可分享
微信分享提示