zoukankan      html  css  js  c++  java
  • Longest Common Substring II SPOJ

    题目链接

    题意:求n个字符串的公共子串(n<=10,len(s[i])<=100000)

    思路:将第一个字符串建立sam,把其他字符串跑到sam的每个节点的最长匹配长度记录下来。然后对于每个结点取最小,用dp数组记录。但对于每个fa[i],应该dp[fa[i]]=max(dp[fa[i]],dp[i]);

    dp数组中最大即为答案。

    应该按topu序来的,应该是数据水了。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn=100010;
    char s[maxn];
    struct Suffix_Automaton{
        //basic
        int nxt[maxn*2][26], fa[maxn*2], l[maxn*2];
        int last,cnt;
        int mm[2*maxn];
        int dp[2*maxn];
        Suffix_Automaton(){ clear(); }
        void clear(){
            last =cnt=1;
            fa[1]=l[1]=0;
            memset(nxt[1],0,sizeof nxt[1]);
        }
        void init(char *s){
            memset(dp,0x3f,sizeof(dp));
            while (*s){
                add(*s-'a');s++;
            }
        }
        void add(int c){
            int p = last;
            int np = ++cnt;
            memset(nxt[cnt],0,sizeof nxt[cnt]);
            l[np] = l[p]+1;last = np;
            while (p&&!nxt[p][c])nxt[p][c] = np,p = fa[p];
            if (!p)fa[np]=1;
            else{
                int q = nxt[p][c];
                if (l[q]==l[p]+1)fa[np] =q;
                else{
                    int nq = ++ cnt;
                    l[nq] = l[p]+1;
                    memcpy(nxt[nq],nxt[q],sizeof (nxt[q]));
                    fa[nq] =fa[q];fa[np] = fa[q] =nq;
                    while (nxt[p][c]==q)nxt[p][c] =nq,p = fa[p];
                }
            }
        }
        void lcs(char *s)
        {
            int n=strlen(s);
            int cur=1;
            int y=0;
            memset(mm,0,sizeof(mm));
            for(int i=0;i<n;i++)
            {
                int c=s[i]-'a';
                if(!nxt[cur][c])
                {
                    while(cur&&!nxt[cur][c])
                        cur=fa[cur];
                    y=l[cur]+1;
                }
                else
                {
                    y++;
                }
                cur=cur?nxt[cur][c]:1;
                if(cur==1)
                    y=0;
                mm[cur]=max(mm[cur],y);
                //printf("%d
    ",mm[cur]);
            }
            for(int i=cnt;i>=1;i--)
            {
                dp[i]=min(dp[i],mm[i]);
                //printf("%d
    ",dp[i]);
                dp[fa[i]]=max(dp[fa[i]],dp[i]);
            }
         } 
         int query()
         {
             int ans=0;
             for(int i=1;i<=cnt;i++)
             {
                 ans=max(dp[i],ans);
             }
             return ans;
         }
    }sam;
    int main()
    {
        scanf("%s",s);
        int n=strlen(s);
        sam.init(s);
        int ans;
        while(~scanf("%s",s)){
            sam.lcs(s);
        }
        printf("%d
    ",sam.query());
     } 
  • 相关阅读:
    谜题48:我所得到的都是静态的
    谜题47:啊呀!我的猫变成狗了
    谜题46:令人混淆的构造器案例
    谜题45:令人疲惫不堪的测验
    谜题44:切掉类
    Python--csv文件处理
    Python装饰器
    Python单例模式
    <<Senium2自动化测试>>读书笔记二
    python之内置函数
  • 原文地址:https://www.cnblogs.com/2462478392Lee/p/13781789.html
Copyright © 2011-2022 走看看