zoukankan      html  css  js  c++  java
  • SPOJ LCS 后缀自动机找最大公共子串

     这里用第一个字符串构建完成后缀自动机以后

    不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加1

    如果找不到,那么就不断沿着后缀树不断往前找到所能匹配到当前字符的最大长度,然后将cur节点转移到当前节点即可,再把答案加1

    记住不断更新所能得到的最大值

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 #define M 26
     7 #define N 600000
     8 int cnt;
     9 char s1[N] , s2[N];
    10 
    11 struct SamNode{
    12     SamNode *son[M] , *f;
    13     int l;
    14 }sam[N] , *root , *last;
    15 
    16 void init()
    17 {
    18     memset(sam , 0 , sizeof(sam));
    19     root = last = &sam[cnt=0];
    20 }
    21 
    22 void add(int x)
    23 {
    24     SamNode *p = &sam[++cnt] , *jp = last;
    25     p->l = jp->l+1;
    26     last = p;
    27     for(; jp&&!jp->son[x] ; jp=jp->f) jp->son[x] = p;
    28     if(!jp) p->f = root;
    29     else{
    30         if(jp->l+1 == jp->son[x]->l) p->f = jp->son[x];
    31         else{
    32             SamNode *r = &sam[++cnt] , *q = jp->son[x];
    33             *r = *q;
    34             r->l = jp->l+1; q->f = p->f = r;
    35             for(; jp && jp->son[x]==q ; jp=jp->f) jp->son[x]=r;
    36         }
    37     }
    38 }
    39 
    40 int solve(int len)
    41 {
    42     int ret = 0 , maxn=0;
    43     SamNode *cur = root;
    44     for(int i=0 ; i<len ; i++){
    45         int x = s2[i]-'a';
    46         if(cur->son[x]){
    47             ret++;
    48             cur = cur->son[x];
    49         }
    50         else{
    51             while(cur && !cur->son[x]) cur = cur->f;
    52             if(!cur) cur = root , ret=0;
    53             else{
    54                 ret = cur->l+1;
    55                 cur = cur->son[x];
    56             }
    57         }
    58         maxn = max(maxn , ret);
    59     }
    60     return maxn;
    61 }
    62 
    63 int main()
    64 {
    65    // freopen("in.txt" , "r" , stdin);
    66    // freopen("out.txt" , "w" , stdout);
    67     scanf("%s%s" , s1 , s2);
    68     init();
    69     int len1 = strlen(s1) , len2 = strlen(s2);
    70     for(int i=0 ; i<len1 ; i++) add(s1[i]-'a');
    71     int ret = solve(len2);
    72     printf("%d
    " , ret);
    73     return 0;
    74 }
  • 相关阅读:
    Android——Activity去除标题栏和状态栏
    Android——程序员的情怀——优化BaseAdapter
    Android——Android Sutido:[2]导入eclipse项目篇
    【Android开源项目分析】自定义圆形头像CircleImageView的使用和源码分析
    学佛略要
    Keystone, Start, Failed to Load Bson
    又梦见了你
    伦敦之旅
    无题
    Multiverse in Doctor Strange // Multiverse在《神秘博士》
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4587476.html
Copyright © 2011-2022 走看看