• spoj Longest Common Substring (多串求最大公共子序列)


    题目链接:

    https://vjudge.net/problem/SPOJ-LCS

    题意:

    最多10行字符串

    求最大公共子序列

    数据范围:

    $1leq |S| leq100000$

    分析: 

    让他们都和第一个字符串匹配,算出每个字符串与第一个字符串的,以$i$位置(i指的是在s1中的位置)结尾匹配的最大长度

    与其它字符串的匹配取最小值

    最后对所有位置取最大值

    超时代码:(题限是236ms,这个代码跑2000ms没问题)

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=500000*2+7;
    char S[maxn];
    char S1[maxn/2];
    int ans[maxn/2];
    int n,a,b,len1,len2;
    struct suffixautomation
    {
        int mp[maxn*2][30],fa[maxn*2],ed,ct,len[maxn*2],minpos[maxn*2],maxpos[maxn*2],deg[maxn*2];
        int res[maxn/2];
        suffixautomation(){
            for(int i=0;i<maxn*2;i++)minpos[i]=1e9,maxpos[i]=-1;
            ed=ct=1;}
        inline void ins(int c,int pos)
        {
            int p=ed;ed=++ct;minpos[ed]=maxpos[ed]=pos;len[ed]=pos;//先初始化size和len
            for(;p&&mp[p][c]==0;p=fa[p]){mp[p][c]=ed;}//然后顺着parent树的路径向上找
            if(p==0){fa[ed]=1;return;}int q=mp[p][c];//case1
            if(len[p]+1==len[q]){fa[ed]=q;return;}//case2
            len[++ct]=len[p]+1;//case 3
            for(int i=1;i<=26;i++){mp[ct][i]=mp[q][i];}
            fa[ct]=fa[q];fa[q]=ct;fa[ed]=ct;
            for(int i=p;mp[i][c]==q;i=fa[i]){mp[i][c]=ct;}
        }
        void solve(){
    
            for(int i=1;i<=ct;i++)deg[fa[i]]++;
            queue<int>que;
            for(int i=1;i<=ct;i++)if(deg[i]==0)que.push(i);
            while(que.size()){
                int x=que.front();
                int y=fa[x];
                que.pop();
                minpos[y]=min(minpos[x],minpos[y]);
                maxpos[y]=max(maxpos[x],maxpos[y]);
                deg[y]--;
                if(deg[y]==0)que.push(y);
            }
            for(int i=1;i<=ct;i++)
                if(minpos[i]<=len1&&maxpos[i]>=len1+2)
                    res[minpos[i]]=max(res[minpos[i]],len[i]);
        }
    }sam,sam2;
    int main()
    {
    //    cout<<"acfvd"
        for(int i=0;i<maxn/2;i++)ans[i]=1e9;
        scanf("%s",S+1);
        len1=strlen(S+1);
        S[len1+1]='z'+1;
        while(scanf("%s",S1+1)==1){
             len2=strlen(S1+1);
             sam=sam2;
             for(int i=len1+2;i<=len1+len2+1;i++)
                S[i]=S1[i-len1-1];
            for(int i=1;i<=len1+len2+1;i++)sam.ins(S[i]-'a'+1,i);
            sam.solve();
            for(int i=1;i<=len1;i++)
                ans[i]=min(ans[i],sam.res[i]);
        }
        int res=0;
        for(int i=1;i<=len1;i++)
            if(ans[i]!=1e9)res=max(res,ans[i]);
        printf("%d
    ",res);
        return 0;
    }
    

      

  • 相关阅读:
    OEP
    壳的执行过程
    JavaScript RSA算法简单实现(转)
    创建根证书及其子证书
    从零开始学习Sencha Touch MVC应用之十四
    javascript base64
    discuz 文档地址
    虚拟机共享数据
    转Javascript到PHP RSA加密通讯的简单实现
    PHP RSA研究
  • 原文地址:https://www.cnblogs.com/carcar/p/11631745.html
Copyright © 2020-2023  润新知