后缀自动机:

一、模板:
洛谷P3804

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#define ll long long
#define llu unsigned ll
using namespace std;
const int maxn=1000100;
char str[maxn];

int x[maxn<<1],y[maxn<<1];
struct Sam
{
   
    int last,cnt;
    int nt[maxn<<1][26],fa[maxn<<1];
    int len[maxn<<1],sum[maxn<<1];

    void init(void)
    {
   
        last=1;
        cnt=1;
        fa[1]=0;
        len[1]=0;

    }

    void _insert(int c)
    {
   
        int nowp=++cnt,p=last;
        len[nowp]=len[last]+1;

        while(p&&!nt[p][c]) nt[p][c]=nowp,p=fa[p];
        if(!p) fa[nowp]=1;
        else
        {
   
            int q=nt[p][c];
            if(len[q]==len[p]+1) fa[nowp]=q;
            else
            {
   
                int nowq=++cnt;
                len[nowq]=len[p]+1;
                memcpy(nt[nowq],nt[q],sizeof(nt[q]));

                fa[nowq]=fa[q];
                fa[nowp]=fa[q]=nowq;

                while(p&&nt[p][c]==q) nt[p][c]=nowq,p=fa[p];
            }
        }
        last=nowp;
        sum[last]=1;
        return ;
    }

    void _count(void)
    {
   
        memset(x,0,sizeof(x));
        for(int i=1;i<=cnt;i++) x[len[i]]++;
        for(int i=1;i<=cnt;i++) x[i]+=x[i-1];
        for(int i=1;i<=cnt;i++) y[x[len[i]]--]=i;
        for(int i=cnt;i>=1;i--)
            sum[fa[y[i]]]+=sum[y[i]];
        return ;

    }

    void creat(void)
    {
   
        int len=strlen(str);

        init();
        for(int i=0;i<len;i++)
            _insert(str[i]-'a');
        _count();

        return ;
    }
}sam;


int main(void)
{
   
    scanf("%s",str);
    sam.creat();
    ll maxx=0;
    for(int i=1;i<=sam.cnt;i++)
        if(sam.sum[i]>1)
            maxx=max((ll)sam.sum[i]*sam.len[i],maxx);

    printf("%lld\n",maxx);
    return 0;
}

二、string string string HDU - 6194 :
求出sum数组即可,判断是否与k相等,若相等,则节点i,代表的字符串都符合题意,求出节点i代表的字符串的个数即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#define ll long long
#define llu unsigned ll
using namespace std;
const int maxn=100100;
char str[maxn];

int x[maxn<<1],y[maxn<<1];
struct Sam
{
   
    int last,cnt;
    int nt[maxn<<1][26],len[maxn<<1];
    int fa[maxn<<1],sum[maxn<<1];

    void init(int n)
    {
   
        last=1;
        cnt=1;
        fa[1]=0;
        len[1]=0;

        for(int i=0;i<=n;i++)
        {
   
            fa[i]=0;
            len[i]=0;
            sum[i]=0;
            memset(nt[i],0,sizeof(nt[i]));
        }
    }

    void _insert(int c)
    {
   
        int nowp=++cnt,p=last;
        len[nowp]=len[last]+1;

        while(p&&!nt[p][c]) nt[p][c]=nowp,p=fa[p];

        if(!p) fa[nowp]=1;
        else
        {
   
            int q=nt[p][c];
            if(len[q]==len[p]+1) fa[nowp]=q;
            else
            {
   
                int nowq=++cnt;
                len[nowq]=len[p]+1;
                memcpy(nt[nowq],nt[q],sizeof(nt[q]));

                fa[nowq]=fa[q];
                fa[nowp]=fa[q]=nowq;

                while(p&&nt[p][c]==q) nt[p][c]=nowq,p=fa[p];
            }
        }
        last=nowp,sum[last]=1;
        return ;
    }

    void _count(void)
    {
   
        memset(x,0,sizeof(x));
        for(int i=1;i<=cnt;i++) x[len[i]]++;
        for(int i=1;i<=cnt;i++) x[i]+=x[i-1];
        for(int i=1;i<=cnt;i++) y[x[len[i]]--]=i;
        for(int i=cnt;i>=1;i--) sum[fa[y[i]]]+=sum[y[i]];
        return ;
    }

    void creat(void)
    {
   
        int len=strlen(str);

        init((len+5)*2);
        for(int i=0;i<len;i++)
            _insert(str[i]-'a'
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值