poj 2774

http://poj.org/problem?id=2774

题意:求两个字符串的最大公共子串

思路:SAM模板

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <iostream>
 5 using namespace std;
 6 #define maxn 100010
 7 
 8 char str[maxn];
 9 
10 struct Node{
11     int len, link, nex[26];
12 }st[maxn << 1];
13 int root, size, last;
14 
15 void init(){
16     root = size = last = 0;
17     st[root].len = 0;
18     st[root].link = -1;
19 }
20 
21 void Extend(int c){
22     int p = last, cur = ++ size;
23     st[cur].len = st[p].len + 1;
24     for(; ~p && st[p].nex[c] == 0; p = st[p].link)
25         st[p].nex[c] = cur;
26     if(p == -1)
27         st[cur].link = root;
28     else{
29         int q = st[p].nex[c];
30         if(st[q].len == st[p].len + 1)
31             st[cur].link = q;
32         else{
33             int clone = ++ size;
34             st[clone] = st[q];
35             st[clone].len = st[p].len + 1;
36             for(; ~p && st[p].nex[c] == q; p = st[p].link)
37                 st[p].nex[c] = clone;
38             st[q].link = st[cur].link = clone;
39         }
40     }
41     last = cur;
42 }
43 
44 
45 
46 
47 int main()
48 {
49     init();
50     scanf("%s",str);
51     int len =strlen(str);
52     for(int i = 0;i<len;i++)
53         Extend(str[i]-'a');
54     scanf("%s",str);
55     len =strlen(str);
56     int n = root,cur = 0,ans = 0;
57     for(int i = 0;i<len;i++)
58     {
59         int tmp = str[i]-'a';
60         if(st[n].nex[tmp])
61             cur++,n = st[n].nex[tmp];
62         else {
63             while(~n&&st[n].nex[tmp]==0)   //字符串段了,从前一个进行匹配
64                 n = st[n].link;
65             if(n==-1)
66                 n = root,cur = 0;     //是否为第一个字符
67             else cur = st[n].len+1,n = st[n].nex[tmp];
68         }
69         ans = max(ans,cur);
70     }
71     printf("%d\n",ans);
72     return 0;
73 }

 

posted @ 2017-04-19 22:41  一个_小菜鸟  阅读(165)  评论(0编辑  收藏  举报