zoukankan      html  css  js  c++  java
  • SPOJ LCS2 多个串的最长公共子串

     这里串最多有10个,找所有串的最长公共子串

    这里后缀自动机做,以第一个串建立后缀自动机,后面的串一个个去匹配,每次得到当前串在可到达状态上所能得到的最长后缀长度

    拿所有串匹配后得到的结果进行计算

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 #define M 26
     6 #define N 200100
     7 char str[N];
     8 struct SamNode{
     9     SamNode *son[M] , *f;
    10     int l , nc , c;
    11 }sam[N] , *last , *root , *b[N];
    12 
    13 int cnt , num[N];
    14 
    15 void init()
    16 {
    17     root = last = &sam[cnt=0];
    18 }
    19 
    20 void add(int x)
    21 {
    22     SamNode *p = &sam[++cnt] , *jp=last;
    23     p->l = jp->l+1 , p->nc = p->l;
    24     last = p;
    25     for( ; jp&&!jp->son[x] ; jp=jp->f) jp->son[x]=p;
    26     if(!jp) p->f = root;
    27     else{
    28         if(jp->l+1 == jp->son[x]->l) p->f = jp->son[x];
    29         else{
    30             SamNode *r = &sam[++cnt] , *q = jp->son[x];
    31             *r = *q;
    32             r->l = r->nc = jp->l+1;
    33             q->f = p->f = r;
    34             for( ; jp && jp->son[x]==q ; jp=jp->f) jp->son[x]=r;
    35         }
    36     }
    37 }
    38 
    39 void solve()
    40 {
    41     int len = strlen(str) , ret;
    42     for(int i=0 ; i<=cnt ; i++) num[sam[i].l]++;
    43     for(int i=1 ; i<=len ; i++) num[i]+=num[i-1];
    44     for(int i=0 ; i<=cnt ; i++) b[--num[sam[i].l]] = &sam[i];
    45     while(~scanf("%s" , str)){
    46         len = strlen(str) , ret=0;
    47         SamNode *cur = root;
    48         for(int i=0 ; i<len ; i++){
    49             int x = str[i]-'a';
    50             if(cur->son[x]){
    51                 ret++;
    52                 cur = cur->son[x];
    53             }
    54             else{
    55                 while(cur && !cur->son[x]) cur = cur->f;
    56                 if(!cur){
    57                     cur = root;
    58                     ret = 0;
    59                 }else{
    60                     ret = cur->l+1;
    61                     cur = cur->son[x];
    62                 }
    63             }
    64             cur->c = max(cur->c , ret);
    65         }
    66         for(int i=cnt ; i>0 ; i--){
    67             b[i]->nc = min(b[i]->nc , b[i]->c);
    68             //子节点可接受到的后缀父节点必定能够接收到,反之却不一定
    69             b[i]->f->c = max(b[i]->f->c , b[i]->c);
    70             b[i]->c = 0;
    71         }
    72     }
    73 }
    74 
    75 int main() {
    76 //    freopen("a.in" , "r" , stdin);
    77     scanf("%s" , str);
    78     init();
    79     int len = (int)strlen(str);
    80     for(int i=0 ; i<len ; i++) add(str[i]-'a');
    81     solve();
    82     int ret = 0;
    83     SamNode *cur;
    84     for(int i=1 ; i<=cnt ; i++){
    85         cur = &sam[i];
    86         ret = max(cur->nc , ret);
    87     }
    88     printf("%d
    " , ret);
    89     return 0;
    90 }
  • 相关阅读:
    vbscript 语言通过序列和ADODB实现取号不重复
    arcgisserver成功发布服务后,浏览服务,无地图显示
    GUID的获取
    EasyUi 表格自适应宽度
    接口隔离原则
    依赖倒置原则
    开放封闭原则
    单一职责原则
    python-函数基础
    python -流程控制
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4587502.html
Copyright © 2011-2022 走看看