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 ",ans); 72 return 0; 73 }