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
  • 相关阅读:
    在 mac iTerm2 中使用 cmd 终端
    在 jupyter 中添加菜单和自动完成功能
    Bash 和 Zsh 开启 vi-mode
    免密登录和远程执行命令
    图片的筛选
    win10 右键菜单很慢的解决方式
    ssh中的 Connection closed by ***
    NodeJS 获取网页源代码
    在 JSDOM v11 中使用jQuery
    kafaka学习
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8118783.html
Copyright © 2011-2022 走看看