第一遍读完这道题,这不就是个裸的KMP板子吗,然后迅速打出了KMP,发现并过不了样例2,于是又仔细读了一下题,发现读漏了一个条件,即需要在中间也出现过,因为我们知道,KMP中的next数组存的是相同的前缀和后缀的长度,那么只需要找在中间出现过前缀长度,并标记一下就行了,最后在匹配的时候多判断一下。

详见代码

#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e6 + 5;

string s;
int net[N], num[N];
bool is[N];

int main()
{
cin >> s;
for (int i = 1, j = 0; s[i]; i++)
{
while (j && s[i] != s[j])
j = net[j - 1];
if (s[i] == s[j])
j++;
net[i] = j;
}//求next
int len = s.length();
for (int i = 1, j = 0; i < len - 1; i++)
{
while (j && s[i] != s[j])
j = net[j - 1];
if (s[i] == s[j])
j++;
is[j] = true;
}//找出中间出现过的前缀的长度
int j = 0;
for (int i = 0; i < len; i++)
{
while (j && s[i] != s[j])
j = net[j - 1];
if (s[i] == s[j])
j++;
while (j && !is[j])
j = net[j - 1];//判断是否在中间出现过
}//匹配
if (!j)
cout << "Just a legend";
else
for (int i = 0; i < j; i++)
cout << s[i];
return 0;
}