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

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

 

 posted on 2015-06-19 00:57  Love风吟  阅读(312)  评论(0编辑  收藏  举报