• SPOJ1812 LCS2


    LCS2 - Longest Common Substring II

    多个字符串找最长公共子串
    以其中一个串建(SAM),然后用其他串一个个去匹配,每次的匹配方式和两个串找(LCS)一样,就是要记录(SAM)的每个状态和当前匹配串匹配的最大值(maxx),这个在匹配完一个串之后需要通过(parent)树上传最大匹配值,同时要更新一个最小值(minn),来表示每个节点和当前已经匹配过的所有串能匹配上的最大值,这个需要每次匹配一个串之后和当前节点的(maxx)(min)

    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MAXN = 2e5+7;
    struct SAM{
        int len[MAXN],link[MAXN],ch[MAXN][26],tot,last,minn[MAXN],maxx[MAXN],c[MAXN],sa[MAXN];
        SAM(){ link[0] = -1; }
        void extend(int c){
            int np = ++tot, p = last;
            minn[np] = MAXN;
            len[np] = len[p] + 1;
            while(p!=-1 and !ch[p][c]){
                ch[p][c] = np;
                p = link[p];
            }
            if(p==-1) link[np] = 0;
            else{
                int q = ch[p][c];
                if(len[p]+1==len[q]) link[np] = q;
                else{
                    int clone = ++tot;
                    minn[clone] = MAXN;
                    link[clone] = link[q];
                    len[clone] = len[p] + 1;
                    memcpy(ch[clone],ch[q],sizeof(ch[q]));
                    link[np] = link[q] = clone;
                    while(p!=-1 and ch[p][c]==q){
                        ch[p][c] = clone;
                        p = link[p];
                    }
                }
            }
            last = np;
        }
        void Radix_sort(){
            for(int i = 1; i <= tot; i++) c[i] = 0;
            for(int i = 0; i <= tot; i++) c[len[i]]++;
            for(int i = 1; i <= tot; i++) c[i] += c[i-1];
            for(int i = tot; i >= 0; i--) sa[c[len[i]]--] = i;
        }
        void match(char *s){
            int u = 0, ls = 0;
            for(int i = 0, l = strlen(s); i < l; i++){
                int c = s[i] - 'a';
                while(u and !ch[u][c]) u = link[u], ls = len[u];
                if(ch[u][c]) u = ch[u][c], ls++;
                maxx[u] = max(maxx[u],ls);
            }
            for(int i = tot + 1; i >= 1 and sa[i]; i--){
                int u = sa[i];
                minn[u] = min(minn[u],maxx[u]);
                maxx[link[u]] = max(maxx[link[u]],min(len[link[u]],maxx[u]));
                maxx[u] = 0;
            }
        }
        int LCS(){ int ret = 0; for(int i = 0; i <= tot; i++) ret = max(ret,minn[i]); return ret; }
    }sam;
    char s[MAXN];
    int main(){
        scanf("%s",s);
        for(int i = 0, l = strlen(s); i < l; i++) sam.extend(s[i]-'a');
        sam.Radix_sort();
        while(scanf("%s",s)!=EOF) sam.match(s);
        printf("%d
    ",sam.LCS());
        return 0;
    }
    
  • 相关阅读:
    世界人工智能大会记录
    [AI开发]将深度学习技术应用到实际项目
    [AI开发]centOS7.5上基于keras/tensorflow深度学习环境搭建
    [AI开发]视频多目标跟踪高级版(离自动驾驶又‘近’了一点点)
    [AI开发]基于深度学习的视频多目标跟踪实现
    [AI开发]Python+Tensorflow打造自己的计算机视觉API服务
    自己实现斗地主引擎
    Pycharm 2017.1 激活服务器
    adb无线网络调试
    adb devices连接提示 Android offline或unauthorized的解决办法
  • 原文地址:https://www.cnblogs.com/kikokiko/p/12704280.html
Copyright © 2020-2023  润新知