[CF126B] Password - KMP
Description
给你一个字符串S(|S|<=1000000),找到既是S前缀又是S后缀又在S中间出现过(既不是S前缀又不是S后缀)的子串,如果不存在输出“Just a legend”。
Solution
从 n 开始沿着 KMP 的 next 迭代,这些串是备选的,现在要考察他们是否在中间出现
记录下 next 数组中间部分的最大值,当找到第一个长度不超过那个最大值时,就是答案
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
int fail[N], n;
string str;
signed main()
{
ios::sync_with_stdio(false);
cin >> str;
n = str.length();
str = " " + str;
fail[1] = 0;
int j = 0;
for (int i = 2; i <= n; i++)
{
while (j && str[i] != str[j + 1])
j = fail[j];
if (str[i] == str[j + 1])
++j;
fail[i] = j;
}
int mx = 0;
for (int i = 2; i < n; i++)
mx = max(mx, fail[i]);
int p = fail[n];
while (p > mx)
p = fail[p];
if (p)
{
for (int i = 1; i <= p; i++)
cout << str[i];
}
else
{
cout << "Just a legend";
}
}