#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <deque>
#include <iostream>
using namespace std;
typedef long long LL;
const int MOD = 1000000007;
const int maxn = 40009 + 5;
int tree[maxn][30];
int sum[maxn];
int tot;
char ss[maxn], mid[maxn], ans[maxn];
void insert(char *str)
{
int len = strlen(str);
int root = 0;
for (int i = 0; i < len; i++)
{
int id = str[i] - 'a';
if (!tree[root][id])
tree[root][id] = ++tot;
if (sum[tree[root][id]] + 1 >= 1)
{
sum[tree[root][id]] = 1;
}
else
{
break;
}
root = tree[root][id];
}
}
int find(char *str, int x)
{
int len = strlen(str);
int root = 0, deep = 0;
for (int i = 0; i < len; i++)
{
int id = str[i] - 'a';
if (tree[root][id])
{
if (sum[tree[root][id]] + 1 >= x)
{
sum[tree[root][id]] = x;
deep++;
}
else
{
break;
}
root = tree[root][id];
}
else
{
break;
}
}
return deep;
}
int main()
{
int n, i, j, k, head;
while (scanf("%d", &n) != EOF)
{
if(n == 0)
break;
memset(tree, 0, sizeof(tree));
memset(sum, 0, sizeof(sum));
memset(ans, 0, sizeof(ans));
tot = 1;
for (i = 1; i < n; i++)
{
scanf(" %s", ss);
k = strlen(ss);
//cout << "input: " << ss << endl;
if (i == 1)
{
for (j = 0; j < k; j++)
{
// printf("%s
", &ss[j]);
insert(&ss[j]);
}
}
else
{
for (j = 0; j < k; j++)
{
find(&ss[j], i);
}
}
}
head = 0;
scanf(" %s", ss);
//cout << "Nth: " << ss << endl;
k = strlen(ss);
// cout << "follows " << endl;
for (j = 0; j < k; j++)
{
// cout << &ss[j] << endl;
int len = find(&ss[j], n);
mid[0] = 0;
strncpy(mid, ss + j, len);
mid[len] = 0;
// printf("mid: %s
", mid);
if (len > head || (len == head && strcmp(mid, ans) < 0))
{
head = len;
ans[0] = 0;
strcpy(ans, mid);
// printf("ans: %s
", ans);
}
}
if (head == 0)
{
printf("IDENTITY LOST
");
}
else
{
printf("%s
", ans);
}
// cout << " n: " << n << endl;
}
return 0;
}
后缀树的思想和字典树一样,不过是依次把字符串的所有后缀加入到树中。
需要整理的知识:后缀树的O(n)优化、后缀自动机、后缀数组