zoukankan      html  css  js  c++  java
  • caioj1472: 后缀自动机1:多个串的LCS

    子串母串跑合并答案

    一个点的fail的dep是比任意一条根到这个点路径长度要小的。

    那么改就可以直接来了。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int len,a[2100];
    struct SAM
    {
        int w[30],dep,fail;
    }ch[2100];int cnt,last;
    void insert(int dep,int x)
    {
        int pre=last,now=++cnt; ch[now].dep=dep;
        last=now;
        
        while(pre!=0&&ch[pre].w[x]==0)
            ch[pre].w[x]=now, pre=ch[pre].fail;
        if(pre==0)ch[now].fail=1;
        else
        {
            int nxt=ch[pre].w[x];
            if(ch[nxt].dep==ch[pre].dep+1)ch[now].fail=nxt;
            else
            {
                int nnxt=++cnt;
                ch[nnxt]=ch[nxt];
                ch[nnxt].dep=ch[pre].dep+1;
                
                ch[now].fail=ch[nxt].fail=nnxt;
                while(pre!=0&&ch[pre].w[x]==nxt)
                    ch[pre].w[x]=nnxt, pre=ch[pre].fail;
            }
        }
    }
    int Rsort[2100],sa[2100];
    void sssort()
    {
        for(int i=1;i<=cnt;i++)Rsort[ch[i].dep]++;
        for(int i=1;i<=len;i++)Rsort[i]+=Rsort[i-1];
        for(int i=cnt;i>=1;i--)sa[Rsort[ch[i].dep]--]=i;
    }
    
    int f[2100],g[2100];
    void solve()
    {
        int now=1,L=0;
        memset(f,0,sizeof(f));
        for(int i=1;i<=len;i++)
        {
            int x=a[i];
            while(now!=1&&ch[now].w[x]==0)
                now=ch[now].fail, L=ch[now].dep;
            if(ch[now].w[x]!=0)
            {
                L++;
                now=ch[now].w[x];
                f[now]=max(f[now],L);
            }
        }
        for(int i=cnt;i>=2;i--)
        {
            int x=sa[i],y=ch[sa[i]].fail;
            f[y]=min(ch[y].dep,max(f[y],f[x]));
        }
        
        for(int i=1;i<=cnt;i++)g[i]=min(g[i],f[i]);
    }
    char ss[2100];
    int main()
    {
        scanf("%s",ss+1);len=strlen(ss+1);
        cnt=last=1; ch[1].dep=0;
        for(int i=1;i<=len;i++)
            a[i]=ss[i]-'a'+1, insert(i,a[i]);
        sssort();
        
        memset(g,63,sizeof(g));
        while(scanf("%s",ss+1)!=EOF)
        {
            len=strlen(ss+1);
            for(int i=1;i<=len;i++)a[i]=ss[i]-'a'+1;
            solve();
        }
        
        int ans=0;
        for(int i=1;i<=cnt;i++)ans=max(ans,g[i]);
        if(ans<=3)printf("They are too short!
    ");
        else printf("True
    %d
    ",ans);
        return 0;
    }
  • 相关阅读:
    CF1264E Beautiful League 解题报告
    CF1411G No Game No Life 解题报告
    Data structure on Bitcoin
    bitcoin Cryptography
    弹性布局Flex的基本语法
    Linq操作list
    dt某字段赋值
    List 添加数据
    dt 转 json 转实体
    队列
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10048310.html
Copyright © 2011-2022 走看看