[HDU1403]Longest Common Substring(后缀数组)

Posted 蒟蒻zht的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HDU1403]Longest Common Substring(后缀数组)相关的知识,希望对你有一定的参考价值。

传送门

 

求两个串的公共子串(注意,这个公共子串是连续的一段)

 

把两个串连在一起,中间再加上一个原字符串中不存在的字符,避免过度匹配。

求一遍height,再从height中找满足条件的最大值即可。

为什么只需要相邻两字典序的后缀呢?因为字典序相邻公共前缀一定最大。

 

——代码

技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #define N 200005
 5 #define max(x, y) ((x) > (y) ? (x) : (y))
 6 
 7 int len, n, ans, m = z + 1;
 8 int buc[N], x[N], y[N], sa[N], rank[N], height[N];
 9 char s[N];
10 
11 inline void build_sa()
12 {
13     int i, k, p;
14     for(i = 0; i < m; i++) buc[i] = 0;
15     for(i = 0; i < len; i++) buc[x[i] = s[i]]++;
16     for(i = 1; i < m; i++) buc[i] += buc[i - 1];
17     for(i = len - 1; i >= 0; i--) sa[--buc[x[i]]] = i;
18     for(k = 1; k <= len; k <<= 1)
19     {
20         p = 0;
21         for(i = len - 1; i >= len - k; i--) y[p++] = i;
22         for(i = 0; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
23         for(i = 0; i < m; i++) buc[i] = 0;
24         for(i = 0; i < len; i++) buc[x[y[i]]]++;
25         for(i = 1; i < m; i++) buc[i] += buc[i - 1];
26         for(i = len - 1; i >= 0; i--) sa[--buc[x[y[i]]]] = y[i];
27         std::swap(x, y);
28         p = 1, x[sa[0]] = 0;
29         for(i = 1; i < len; i++)
30             x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
31         if(p >= len) break;
32         m = p;
33     }
34 }
35 
36 inline void build_height()
37 {
38     int i, j, k = 0;
39     for(i = 0; i < len; i++) rank[sa[i]] = i;
40     for(i = 0; i < len; i++)
41     {
42         if(!rank[i]) continue;
43         if(k) k--;
44         j = sa[rank[i] - 1];
45         while(s[i + k] == s[j + k] && i + k < len && j + k < len) k++;
46         height[rank[i]] = k;
47     }
48 }
49 
50 int main()
51 {
52     int i;
53     while(~scanf("%s", s))
54     {
55         n = strlen(s);
56         s[n] = #;
57         scanf("%s", s + n + 1);
58         len = strlen(s);
59         build_sa();
60         build_height();
61         ans = 0; 
62         for(i = 1; i < len; i++)
63             if((sa[i - 1] < n && sa[i] > n) || (sa[i - 1] > n && sa[i] < n))
64                 ans = max(ans, height[i]);
65         printf("%d\n", ans);
66     }
67     return 0;
68 }
View Code

 

以上是关于[HDU1403]Longest Common Substring(后缀数组)的主要内容,如果未能解决你的问题,请参考以下文章

HDU1403Longest Common Substring

HDU 1403 Longest Common Substring(最长公共前缀)

[HDU1403]Longest Common Substring(后缀数组)

HDU-1403-Longest Common Substring(后缀数组的高度数组运用)

SPOJ 1812 Longest Common Substring II

Longest Common Substring(最长公共子序列)