zoukankan      html  css  js  c++  java
  • 【codevs3160】 LCS 【后缀自动机】

    题意

      给出两个字符串,求它们的最长公共子串。

    分析

      后缀自动机的基础应用。

      比如两个字符串s1和s2,我们把s1建为SAM,然后根据s2跑,找出s2每个前缀的最长公共后缀。

      我们可以理解为,当向尾部增加一个字母的时候,就按照匹配路径来走,当在SAM中找不到这样的字符串的时候,就要减少头部的字母,就顺着parent树往祖先结点走。

      

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <map>
     6 
     7 using namespace std;
     8 const int maxn=1e5+100;
     9 char S[maxn],T[maxn];
    10 int n,m;
    11 struct state{
    12     int len,link;
    13     map<char,int>next;
    14 }st[4*maxn];
    15 int last,cur,sz;
    16 void init(){
    17     last=cur=0;
    18     sz=1;
    19     st[0].len=0;
    20     st[0].link=-1;
    21 //    st[0].next.clear();
    22 }
    23 void build_sam(char c){
    24     cur=sz++;
    25     st[cur].len=st[last].len+1;
    26     int p;
    27     for(p=last;p!=-1&&!st[p].next.count(c);p=st[p].link){
    28         st[p].next[c]=cur;
    29     }
    30     if(p==-1)
    31         st[cur].link=0;
    32     else{
    33         int q=st[p].next[c];
    34         if(st[p].len+1==st[q].len){
    35             st[cur].link=q;
    36         }else{
    37             int clone=sz++;
    38             st[clone].len=st[p].len+1;
    39             st[clone].next=st[q].next;
    40             st[clone].link=st[q].link;
    41             for(;p!=-1&&st[p].next[c]==q;p=st[p].link){
    42                 st[p].next[c]=clone;
    43             }
    44             st[cur].link=st[q].link=clone;
    45         }
    46     }
    47     last=cur;
    48 }
    49 
    50 int main(){
    51     scanf("%s%s",S,T);
    52     n=strlen(S);
    53     m=strlen(T);
    54     init();
    55     for(int i=0;i<n;i++){
    56         build_sam(S[i]);
    57     }
    58     int cur=0;
    59     int v=0,len=0,ans=0;
    60     for(int i=0;i<m;i++){
    61         if(st[v].next.count(T[i])){
    62             v=st[v].next[T[i]];
    63             len++;
    64         }else{
    65             while(v!=-1&&!st[v].next.count(T[i])){
    66                // printf("%d
    ",v);
    67                 v=st[v].link;
    68                 len=st[v].len;
    69             }
    70             if(v==-1)
    71                 v=len=0;
    72             else{
    73                 v=st[v].next[T[i]];
    74                 len++;
    75             }
    76         }
    77         ans=max(ans,len);
    78     }
    79     printf("%d
    ",ans);
    80 
    81 
    82 return 0;
    83 }
    View Code
  • 相关阅读:
    WordPress后台添加侧边栏菜单
    Redis 使用多个数据库及密码配置
    datatable 修改点击列头进行排序顺序
    命令行客户端操作pg数据库常用操作
    pg 创建自增id
    让 PHP COOKIE 立即生效(不用刷新就可以使用)
    js cookie
    使用mysql监视器即命令行下的mysql
    javascript 获取键盘上的按键代码KeyCode
    吞吐量(TPS)、QPS、并发数、响应时间(RT)概念
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9882068.html
Copyright © 2011-2022 走看看