zoukankan      html  css  js  c++  java
  • SPOJ LCS2 Longest Common Substring II ——后缀自动机

    后缀自动机裸题

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i<=k;--i)
    #define inf 0x3f3f3f3f
    #define ll long long
    #define maxn 200005 
     
    struct sam{
        char s[maxn];
        int h[maxn],to[maxn],ne[maxn],en,ttt;
        int dp[maxn][10],n;
        int last,cnt,len,lth;
        int go[maxn][26],l[maxn],fa[maxn];
        void addedge(int a,int b)
        {to[en]=b;ne[en]=h[a];h[a]=en++;}
        void init()
        {
        	memset(h,-1,sizeof h);en=0;
            last=cnt=1;
    //        memset(go,0,sizeof go);
    //        memset(dp,0,sizeof dp);
        }
        void add(int x)
        {
    //      printf("add %d
    ",x);
            int p=last,np=last=++cnt; l[np]=l[p]+1;
    //      printf("on point %d
    ",np);
            for (;p&&!go[p][x];p=fa[p]) go[p][x]=np;
            if (!p) fa[np]=1;
            else
            {
                int q=go[p][x];
                if (l[q]==l[p]+1) fa[np]=q;
                else
                {
                    int nq=++cnt;
                    l[nq]=l[p]+1;
                    memcpy(go[nq],go[q],sizeof go[q]);
                    fa[nq]=fa[q];
                    fa[np]=fa[q]=nq;
                    for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq;
                }
            }
        }
        void dfs(int o)
        {
        	for (int i=h[o];i>=0;i=ne[i])
        	{
        		dfs(to[i]);
        		F(j,1,ttt)
        			dp[o][j]=max(dp[o][j],dp[to[i]][j]);
    		}
    	}
        void solve()
        {
            scanf("%d",&n);
            scanf("%s",s+1);
            lth=len=strlen(s+1);
            F(i,1,lth) add(s[i]-'a');
            int i=0;
            while (scanf("%s",s+1)!=EOF)
            {
            	++i;
    //            scanf("%s",s+1);
                len=strlen(s+1);
                int now=1,t=0;
                F(j,1,len)
                {
                    int x=s[j]-'a';
                    if (go[now][x]) {t++;now=go[now][x];}
                    else
                    {
                        while (now&&!go[now][x]) now=fa[now];
                        if (!now) {t=0;now=1;}
                        else t=l[now]+1,now=go[now][x];
                    }
                    dp[now][i]=max(dp[now][i],t); 
    //                for (int k=now;k;k=fa[k]) dp[k][i]=max(dp[k][i],t);
                }
            }
            dfs(1);
            int ans=0;ttt=i;
            F(i,1,cnt) addedge(fa[i],i);
            F(i,1,cnt)
            {
                int tmp=l[i];
                F(j,2,ttt)
                    tmp=min(tmp,dp[i][j]);
                ans=max(ans,tmp);
            }
            printf("%d
    ",ans);
        }
    }SAM;
     
    int main()
    {
        SAM.init();
        SAM.solve();
    }
    

      

  • 相关阅读:
    NOIP2014D2T2寻找道路(Spfa)
    【割点】【割边】tarjan
    NOIP2013D1T3货车运输(最大生成树+倍增lca)
    lca最近公共祖先(模板)
    人生第一次hash
    【模板】Tarjan求强连通分量
    【模板】链式前向星+spfa
    二叉树的三种遍历
    hdu 3549 最大流
    hdu 1532&&poj1273 基础最大流
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6486947.html
Copyright © 2011-2022 走看看