zoukankan      html  css  js  c++  java
  • 【POJ】2774 Long Long Message

    【题意】给定两个字符串S和T,求最长公共子串。len<=10^5。

    【算法】后缀自动机

    【题解】对字符串S建SAM,然后令串T在S上跑匹配。

    这是自动机最原本的功能——匹配,就是串T在SAM(S)上走,不能匹配就沿失配边走,这样得到的是T上以每个字符结尾的子串中与S的最长公共子串,取Max即是答案。

    注意失配不要走到0节点处。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=100010;
    struct tree{int len,fa,t[30];}t[maxn*2];
    int last,n,m,tot;
    char s[maxn],T[maxn];
    void insert(int c){
        int np=++tot;
        t[np].len=t[last].len+1;
        int x=last;
        while(x&&!t[x].t[c])t[x].t[c]=np,x=t[x].fa;
        last=np;
        if(!x)t[np].fa=1;else{
            int y=t[x].t[c];
            if(t[y].len==t[x].len+1)t[np].fa=y;else{
                int nq=++tot;
                t[nq]=t[y];
                t[nq].len=t[x].len+1;
                t[nq].fa=t[y].fa;t[np].fa=t[y].fa=nq;
                while(x&&t[x].t[c]==y)t[x].t[c]=nq,x=t[x].fa;
            }
        }
    }
    int main(){
        scanf("%s",T+1);m=strlen(T+1);
        last=tot=1;
        for(int i=1;i<=m;i++)insert(T[i]-'a');
        scanf("%s",s+1);n=strlen(s+1);
        int ans=0,cnt=0,now=1;
        for(int i=1;i<=n;i++){
            while(now!=1&&!t[now].t[s[i]-'a'])now=t[now].fa,cnt=t[now].len;
            if(t[now].t[s[i]-'a'])cnt++,now=t[now].t[s[i]-'a'];else cnt=0;
            ans=max(ans,cnt);
        }
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    js插件-图片椭圆轮播效果
    js-放大镜效果
    vue使用技巧,及遇到的问题
    vue的传参方式和router使用技巧
    关于new Date()的日期格式处理
    图片上传预览
    缓动动画的原理
    input不能输入汉字和负数
    上传格式判断方法
    Vue-cli3.0配置全局less
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8118783.html
Copyright © 2011-2022 走看看