zoukankan      html  css  js  c++  java
  • SPOJ1811最长公共子串问题(后缀自动机)

    转载:http://blog.csdn.net/acdreamers/article/details/10746023

    题意:给两个串A和B,求这两个串的最长公共子串。

    分析:其实本题用后缀数组的DC3已经能很好的解决,这里我们来说说利用后缀自动机如何实现。

    对于串A和B,我们先构造出串A的后缀自动机,那么然后用B串去匹配,对于B,我们一位一位地扫描,维护一个ans值,表示从

    B串的开始到B[i]的这个子串与A的最长公共子串。

    假设现在到B[i-1]的最长公共子串长度为ans,然后我们来看B[i],如果当前节点有B[i]这个孩子,那么直接就len++即可。

    如果没有就找一直向前找pre,直到找到有B[i]这个孩子的节点。

     1 #include <iostream>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <stdio.h>
     5 
     6 using namespace std;
     7 const int N=250005;
     8 
     9 struct State
    10 {
    11     State *pre,*go[26];
    12     int step;
    13     void clear()
    14     {
    15         pre=0;
    16         step=0;
    17         memset(go,0,sizeof(go));
    18     }
    19 }*root,*last;
    20 
    21 State statePool[N*2],*cur;
    22 
    23 void init()
    24 {
    25     cur=statePool;
    26     root=last=cur++;
    27     root->clear();
    28 }
    29 
    30 void Insert(int w)
    31 {
    32     State *p=last;
    33     State *np=cur++;
    34     np->clear();
    35     np->step=p->step+1;
    36     while(p&&!p->go[w])
    37         p->go[w]=np,p=p->pre;
    38     if(p==0)
    39         np->pre=root;
    40     else
    41     {
    42         State *q=p->go[w];
    43         if(p->step+1==q->step)
    44             np->pre=q;
    45         else
    46         {
    47             State *nq=cur++;
    48             nq->clear();
    49             memcpy(nq->go,q->go,sizeof(q->go));
    50             nq->step=p->step+1;
    51             nq->pre=q->pre;
    52             q->pre=nq;
    53             np->pre=nq;
    54             while(p&&p->go[w]==q)
    55                 p->go[w]=nq, p=p->pre;
    56         }
    57     }
    58     last=np;
    59 }
    60 
    61 char A[N],B[N];
    62 
    63 int main()
    64 {
    65     int n,m;
    66     scanf("%s%s",A,B);
    67     n=strlen(A);
    68     m=strlen(B);
    69     init();
    70     for(int i=0; i<n; i++)
    71         Insert(A[i]-'a');
    72     int ans=0,len=0;
    73     State *p=root;
    74     for(int i=0; i<m; i++)
    75     {
    76         int x=B[i]-'a';
    77         if(p->go[x])
    78         {
    79             len++;
    80             p=p->go[x];
    81         }
    82         else
    83         {
    84             while(p&&!p->go[x]) p=p->pre;
    85             if(!p) p=root,len=0;
    86             else   len=p->step+1,p=p->go[x];
    87         }
    88         ans=max(ans,len);
    89     }
    90     printf("%d
    ",ans);
    91     return 0;
    92 }
  • 相关阅读:
    hdu5249
    hdu5673-Robot
    hihoCoder 1033
    simpleOS 1.0
    hdu3511-Prison Break
    单调栈
    关于每次取PC的值为PC+4的问题
    hdu3652
    Linux MySQL5.7.18安装手册
    Linux MySQL5.6.36安装手册
  • 原文地址:https://www.cnblogs.com/agenthtb/p/7696112.html
Copyright © 2011-2022 走看看