码迷,mamicode.com
首页 > 其他好文 > 详细

SPOJ LCS 后缀自动机找最大公共子串

时间:2015-06-19 01:14:35      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:

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

不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加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\n" , ret);
73     return 0;
74 }

 

SPOJ LCS 后缀自动机找最大公共子串

标签:

原文地址:http://www.cnblogs.com/CSU3901130321/p/4587476.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!