给一个字符串 ,求它的一个最长的子串 ,满足 既是 的前缀,又是 的后缀,又在一个既不是前缀又不是后缀的地方出现。
如果没有这样的子串,输出Just a legend
.
性质很强,解法很多。
比如求得前缀函数,然后从大到小遍历整个字符串的所有候选border,看有没有一个位置的前缀函数值等于这个候选border.(实际上从第二个开始一定有).
- WA一次,因为我检查候选border的方式写成了
cnt>1
。但实际上cnt=1
是可行的,因为这个候选border并一定不会在整个字符串的前缀函数里出现。 - 这个题需要对前缀函数的性质有很好的了解,适合kmp算法的掌握测试。
/* LittleFall : Hello! */
#include <bits/stdc++.h>
using namespace std; using ll = long long; inline int read();
const int M = 1000016, MOD = 1000000007;
char str[M];
int fail[M], cnt[M];
int main(void)
{
#ifdef _LITTLEFALL_
freopen("in.txt","r",stdin);
#endif
scanf("%s",str);
int n = strlen(str);
for(int i=1, j=0; str[i]; ++i)
{
while(j && str[i]!=str[j]) j=fail[j-1];
fail[i] = str[i]==str[j] ? ++j : 0;
cnt[fail[i]]++;
}
int j = fail[n-1];
if(cnt[j]==1) j = fail[j-1];
printf("%s\n", j ? str+n-j : "Just a legend" );
return 0;
}
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}