这里串最多有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\n" , ret);
89     return 0;
90 }

 

 posted on 2015-06-19 02:01  Love风吟  阅读(226)  评论(0编辑  收藏  举报