分析:给定一个字符串,查找既是前缀又是后缀且在中间部分出现的最长子串。
模式字符串记为P(下标从0开始),next[q] = k 表示P[q]之前的子串中,存在长度为k的相同前缀和后缀,即P[0]~P[k-1]与P[q-k]~P[q-1]依次相同。
所以只要判断Next[i]是否在中间出现过即可,使用set容器记录。
代码如下:
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
const int maxn = 1e6+10;
int Next[maxn];
int n;
char s[maxn];
bool flag;
set<int>v;
void make_next(){
Next[0] = Next[1] = 0;
for (int i=1; i<n; i++) {
int j = Next[i];
while (j && s[i]!=s[j]) j = Next[j];
Next[i+1] = s[j]==s[i]?j+1:0;
}
}
int main(){
while (scanf("%s",s)!=EOF){
n = strlen(s);
make_next();
v.clear();
for (int i=0; i<n; i++) v.insert(Next[i]);
flag = 0;
int x = n;
while (Next[x]){
if (v.count(Next[x])) {
flag = 1;
for (int i=0; i<Next[x]; i++) printf("%c",s[i]);
printf("\n");
break;
}
x = Next[x];
}
if (!flag) printf("Just a legend\n");
}
return 0;
}