• 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 }
  • 相关阅读:
    寒假学习24idea连接mongo
    安装破解project
    寒假学习19FileZilla连接centos7失败处理(SSH)
    寒假学习22IDEA Junit4配置
    寒假学习25javaswing 入门介绍
    寒假学习20VS Code中格式化插件PrettierCode Formatter保姆级设置
    空3
    7
    kafka集群搭建及启动脚本
    空6
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4587476.html
Copyright © 2020-2023  润新知