Hdu1403 Longest Common Substring
2018-03-11 13:45
399 查看
Longest Common Substring
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7335 Accepted Submission(s): 2580
[align=left]Problem Description[/align]
Given two strings, you have to tell the length of the Longest Common Substring of them.
For example:
str1 = banana
str2 = cianaic
So the Longest Common Substring is "ana", and the length is 3.
[align=left]Input[/align]
The input contains several test cases. Each test case contains two strings, each string will have at most 100000 characters. All the characters are in lower-case.
Process to the end of file.
[align=left]Output[/align]
For each test case, you have to tell the length of the Longest Common Substring of them.
[align=left]Sample Input[/align]
banana
cianaic
[align=left]Sample Output[/align]
3
[align=left]Author[/align]
Ignatius.L
题目大意:求两个字符串的后缀的LCP.
分析:后缀数组的经典应用.
把两个字符串拼起来,中间用一个特殊字符隔开.对这一整体字符串求height数组,如果height[i]比ans大,并且sa[i-1],sa[i]分布在两个字符串中,就更新ans.
注意多组数据数组清空的问题!我没有清空fir和sec数组,导致一直RE.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1000010; char s1[maxn],s2[maxn],s[maxn]; int len1,len2,len,sett[maxn],a[maxn],cnt,fir[maxn],sec[maxn],tong[maxn],pos[maxn]; int rk[maxn],sa[maxn],ht[maxn],ans,poss; void solve() { memset(rk,0,sizeof(rk)); memset(sa,0,sizeof(sa)); memset(ht,0,sizeof(ht)); memset(fir,0,sizeof(fir)); memset(sec,0,sizeof(sec)); memset(pos,0,sizeof(pos)); memset(tong,0,sizeof(tong)); copy(s + 1,s + len + 1,sett + 1); sort(sett + 1,sett + 1 + len); cnt = unique(sett + 1,sett + 1 + len) - sett - 1; for (int i = 1; i <= len; i++) a[i] = lower_bound(sett + 1,sett + 1 + cnt,s[i]) - sett; for (int i = 1; i <= len; i++) tong[a[i]]++; for (int i = 1; i <= len; i++) tong[i] += tong[i - 1]; for (int i = 1; i <= len; i++) rk[i] = tong[a[i] - 1] + 1; for (int t = 1; t <= len; t *= 2) { for (int i = 1; i <= len; i++) fir[i] = rk[i]; for (int i = 1; i <= len; i++) { if (i + t > len) sec[i] = 0; else sec[i] = rk[i + t]; } fill(tong,tong + 1 + len,0); for (int i = 1; i <= len; i++) tong[sec[i]]++; for (int i = 1; i <= len; i++) tong[i] += tong[i - 1]; for (int i = 1; i <= len; i++) pos[len - --tong[sec[i]]] = i; fill(tong,tong + 1 + len,0); for (int i = 1; i <= len; i++) tong[fir[i]]++; for (int i = 1; i <= len; i++) tong[i] += tong[i - 1]; for (int i = 1; i <= len; i++) { int temp = pos[i]; sa[tong[fir[temp]]--] = temp; } bool flag = true; int last = 0; for (int i = 1; i <= len; i++) { int temp = sa[i]; if (!last) rk[temp] = 1; else if (fir[temp] == fir[last] && sec[temp] == sec[last]) { rk[temp] = rk[last]; flag = false; } else rk[temp] = rk[last] + 1; last = temp; } if (flag) break; } int k = 0; for (int i = 1; i <= len; i++) { if (rk[i] == 1) k = 0; else { if (k) k--; int j = sa[rk[i] - 1]; while (i + k <= len && j + k <= len && a[i + k] == a[j + k]) k++; } ht[rk[i]] = k; } } int main() { while (~scanf("%s",s1 + 1)) { len = ans = 0; len1 = strlen(s1 + 1); scanf("%s",s2 + 1); len2 = strlen(s2 + 1); for (int i = 1; i <= len1; i++) s[++len] = s1[i]; s[++len] = '&'; poss = len; for (int i = 1; i <= len2; i++) s[++len] = s2[i]; solve(); for (int i = 2; i <= len; i++) if (ht[i] > ans && ((sa[i - 1] < poss && sa[i] > poss) || (sa[i - 1] > poss && sa[i] < poss))) ans = ht[i]; printf("%d\n",ans); } return 0; }
相关文章推荐
- hdu1403---Longest Common Substring(后缀数组求2个字符串的最长公共子串)
- POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203
- HDU 1403 Longest Common Substring
- HDU 1403 Longest Common Substring
- hdu 1403 Longest Common Substring (后缀数组模板)
- hdu 1403 Longest Common Substring (后缀数组模板题)
- HDU 1403 & POJ 2774 Longest Common Substring (后缀数组啊 求最长公共子串 模板题)
- hdu1403 Longest Common Substring
- HDU 1403 Longest Common Substring
- hdu 1403 Longest Common Substring - 后缀数组
- HDU 1403 Longest Common Substring(后缀数组入门)
- 【hdu 1403】Longest Common Substring
- hdu-1403-Longest Common Substring
- HDU 1403-Longest Common Substring (后缀数组)
- HDU 1403 Longest Common Substring(后缀数组 最长公共子串)
- HDU 1403 Longest Common Substring(后缀数组,最长公共子串)
- 【HDU】1403 Longest Common Substring
- hdu 1403 Longest Common Substring 后缀数组求最长公共子串
- hdu 1403 Longest Common Substring
- hdu 1403 Longest Common Substring 后缀数组求最长公共子串