#include <stdio.h>
#include <string.h>
#define DEBUG
#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__)
#else
#define debug(...)
#endif
#define maxn 200004
#define MIN(a, b) (a) < (b) ? (a) : (b)
int wx[maxn],wy[maxn],c[maxn], h[maxn];
int sa[maxn], *rank, height[maxn];
int cmp(int *r,int a,int b,int l)
{
return r[a] == r[b] && r[a+l] == r[b+l]; /* r[a] == r[b]就意味着a+l和b+l不会越界 */
}
/* 倍增法求后缀数组, 所有数组都从下标0开始 */
void da(char *r,int *sa,int n,int m)
{
int i,l,p,*x=wx,*y=wy,*t;
// 初始化x[i],同时根据源字符串r得到第一轮的SA
for(i = 0; i <= m; i++) c[i] = 0;
for(i = 0; i < n; i++) c[x[i] = r[i]]++;
for(i = 1; i <= m; i++) c[i] += c[i-1];
for(i = n-1; i >= 0; i--) sa[--c[r[i]]] = i;
//继续迭代,根据x计算SA
for(l = 1,p = 1; p < n; l <<= 1, m = p) /* p表示不同字符串的个数, p = n说明排序结束 */
{
// 根据上一次求出的sa,对第二关键字排序,结果保存在y[i]中, y[i] = j表示第i名的后缀是suffix[j]
for(p = 0,i = n-l; i < n; i++) { /* 第二关键字超出范围的后缀排在最前面 */
y[p++] = i;
}
for(i = 0; i < n; i++) {
if(sa[i] >= l) {
y[p++] = sa[i]-l;
}
}
//对第一关键字使用计数排序, 生成SA
for(i = 0; i <= m; i++) c[i] = 0;
for(i = 0; i < n; i++) c[x[y[i]]]++;
for(i = 1; i <= m; i++) c[i] += c[i-1];
for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
//根据SA生成rank,保存在数组x中,x[i] = j表示suffix[i]排在第j位, 相同的后缀名次相同,
//所以还要根据上次的x数组来判断两个后缀是否一样,优化点:
//交换x和y,这样y指向上次的x,原来y指向的空间用来存放新生成的rank
for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i++) {
x[sa[i]] = cmp(y, sa[i-1], sa[i], l) ? p-1 : p++;
}
}
rank = x;
}
int main()
{
int i, s, t, n, n1, max_len;
char r[maxn], line[maxn];
gets(r);
n1 = strlen(r);
gets(line);
strcat(r, line);
n = strlen(r)+1; /* 一定要把末尾的\0也算进去 */
max_len = -1;
// 求后缀数组sa和排名数组wy
da(r, sa, n, 156);
// 求h[0]...h[n-1]
for (i = 0; i < n; i++) {
if (rank[i] == 1) h[i] = 0;
else if (i == 0 || h[i-1] <= 1) {
for (s = i, t = sa[rank[i]-1], h[i] = 0; r[s++] == r[t++]; h[i]++);
}
else {
h[i] = h[i-1]-1;
for (s = i+h[i], t = sa[rank[i]-1]+h[i]; r[s++] == r[t++]; h[i]++);
}
}
//求height[1]...height[n]
height[1] = 0;
for (i = 2; i <= n; i++) {
height[i] = h[sa[i]];
// 后缀的最长前缀肯定出现在两个排名相邻的后缀之间,即height[i]的最大值
// 而且两个后缀要属于不同的字符串
if (((sa[i] < n1 && sa[i-1] >= n1) || (sa[i-1] < n1 && sa[i] >= n1)) && height[i] > max_len) {
max_len = height[i];
}
}
printf("%d\n", max_len);
return 0;
}
相关推荐
【POJ 2774】要求求出两个字符串的最长公共子串,这可以通过后缀数组和LCP(Longest Common Prefix,最长公共前后缀)数组直接计算得出。 【POJ 3693】的问题更复杂一些,需要找出字符串中重复次数最多的连续重复子...
《POJ 3261:深入理解后缀数组及其应用》 在计算机科学与信息技术领域,算法设计和分析是核心部分,而字符串处理问题是其中不可或缺的议题。POJ 3261是一道经典的在线编程竞赛题目,它涉及到一个重要的数据结构——...
通过了解后缀数组,我们可以解决如poj3261这样的模板题。 对于后缀数组的入门,推荐阅读的两篇文章是: 1. https://www.cnblogs.com/nietzsche-oier/articles/6621881.html 2. ...
11. POJ——2694 逆波兰表达式:这是一个关于后缀表达式(逆波兰表示法)的题目,需要理解运算符优先级,并能实现表达式求值的算法。 12. POJ——2696 计算表达式的值:可能涉及到表达式解析,可以使用栈数据结构来...
poj上的题,音乐主题,首先需要对给定的数组差分,之后就是用后缀数组就行
- POJ 2031、POJ 1039:后缀数组的构建与应用。 #### 字典树 (Trie) - **题目示例**: - POJ 2513:Trie树的基本构造与查询。 ### 编程技巧 #### C++模板应用 - **题目示例**: - POJ 3096、POJ 3007:模板...
- 字符串处理:如KMP算法和后缀数组,用于字符串搜索和模式匹配,如`poj1035, poj3080`。 - 排序算法:如快速排序和归并排序,用于对数据进行排序,如`poj2388, poj2299`。 - 并查集:用于处理集合的合并和查询...
"algorithms-and-data-structures.rar_algorithms"这个压缩包文件聚焦于几个关键的算法和概念,包括线段树、后缀数组、最大权闭合子图、求逆元、斜率优化以及强连通分量。下面我们将详细探讨这些知识点。 1. **线段...
- 后缀数组可以高效地解决字符串相关问题。 4. **区间查询** - 推荐题目:[poj3264](https://vjudge.net/problem/POJ-3264)、[poj3368](https://vjudge.net/problem/POJ-3368) - 区间查询问题通常涉及线段树或...
5. **后缀数组/后缀自动机**: - (poj1703, 2492):用于文本检索的强大工具。 6. **KMP算法**: - (poj1961, poj2406):高效的字符串匹配算法。 ### 十、进阶状态压缩 1. **状态压缩技巧**: - 如何高效地表示...
字符串题目记录是 ACM 题目中的一种常见类型,涉及到字符串处理、哈希、后缀数组、KMP 算法等多种知识点。下面是对标题、描述、标签和部分内容的详细解释和知识点总结。 标题:字符串题目记录 该标题表明了问题的...
本资源“各种算法模板”聚焦于两种常见的数据结构和算法:字典树(Trie)和后缀数组(Suffix Array),这些都是在解决编程竞赛如POJ(Programming Online Judge)时经常遇到的工具。 **字典树**,又称为前缀树或...
ACM算法讲解 本文将对ACM主要算法进行讲解,涵盖了基本算法、图算法、数据结构、搜索、计算几何学、动态规划和综合题等多方面的知识点。 一、基本算法 ... + 后缀数组、后缀树 + 块状链表 + 哈夫曼树
8. **字符串处理**:涉及到模式匹配、KMP算法、后缀数组等,对于文本处理和信息检索至关重要。 9. **数学问题**:如数论、组合数学、线性代数等,它们在解决特定类型的算法问题时不可或缺。 10. **递归与分治**:...
- 特殊的数据结构:后缀数组、LCP数组等用于文本处理的高效结构。 #### 6. 几何题 几何题通常涉及到几何图形的性质、计算等。 - **知识点**: - 几何对象的表示方法:点、线、面等。 - 几何计算的基础公式,如...
7. **字符串处理**:涉及到模式匹配、KMP算法、后缀数组或AC自动机等字符串相关的算法。 8. **数学技巧**:可能涉及数论、组合数学、模运算、矩阵快速幂等数学知识。 9. **编码技巧**:在ACM竞赛中,代码效率至关...
- **内容**: 后缀数组是字符串的所有后缀按字典序排序后的数组。 - **示例题目**: poj3278, poj1426, poj3126, poj3087, poj3414 #### 4. 字符串搜索 - **内容**: 包括后缀树、AC自动机等字符串搜索算法。 - **...
ACMer 需要掌握的算法讲解 本资源摘要信息涵盖了 ACM 主要算法的介绍,包括基本算法、图算法、数据结构、搜索、计算几何学、动态规划、综合题等方面的知识点。...13. 后缀数组、后缀树 14. 块状链表 15. 哈夫曼树
2. **后缀数组** - 示例题目:poj2031, poj1039 3. **后缀自动机** - 示例题目:poj1408, poj1584 4. **后缀树** - 示例题目:poj2187, poj1113 #### 高级算法 1. **高级搜索** - 示例题目:poj3096, poj...
4. **字符串处理**:KMP算法、后缀数组、Manacher算法等。 5. **数学应用**:组合数学、数论、模运算、矩阵快速幂等。 6. **计算几何**:点线段查询、最短路径、旋转卡壳等。 7. **模拟与建模**:根据题目需求进行的...