Description
Asterix, Obelix and their temporary buddies Suffix and Prefix has finally found the Harmony temple. However, its doors were firmly locked and even Obelix had no luck opening them.
A little later they found a string s, carved on a rock below the temple’s gates. Asterix supposed that that’s the password that opens the temple and read the string aloud. However, nothing happened. Then Asterix supposed that a password is some substring t of the string s.
Prefix supposed that the substring t is the beginning of the string s; Suffix supposed that the substring t should be the end of the string s; and Obelix supposed that t should be located somewhere inside the string s, that is, t is neither its beginning, nor its end.
Asterix chose the substring t so as to please all his companions. Besides, from all acceptable variants Asterix chose the longest one (as Asterix loves long strings). When Asterix read the substring t aloud, the temple doors opened.
You know the string s. Find the substring t or determine that such substring does not exist and all that’s been written above is just a nice legend.
Input
You are given the string s whose length can vary from
1
1
1 to
1
0
6
10^6
106 (inclusive), consisting of small Latin letters.
Output
Print the string t. If a suitable t string does not exist, then print “Just a legend” without the quotes.
Examples
Input
fixprefixsuffix
Output
fix
Input
abcdabc
Output
Just a legend
Main idea
求给定字符串中是否存在一个子串,既是前缀又是后缀,也是非前后缀
Solution 1
利用next数组 + DP 求出所有相同前后缀的出现次数,出现次数大于2的最长前后缀即为答案
和这题相似:Codeforces 432D
Solution 2
hash暴力(居然没有TLE)
Code 1
#include <bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e6 + 5;
char s[maxn];
int nex[maxn];
void find_nex(int m){
int i,j;
j = nex[1] = 0;
i = 2;
while(i <= m){
while(j && s[j+1] != s[i]) j = nex[j];
if(s[j+1] == s[i]) j++;
nex[i++] = j;
}
}
int num[maxn];
void solve(){
int n = strlen(s+1);find_nex(n);
for(int i = n;i > 0;--i){
num[i]++;
num[nex[i]] += num[i];
}
int l = 0;
for(int i = n;i > 0;i = nex[i]){
if(num[i] >= 3){
l = i;break;
}
}
if(l == 0) printf("Just a legend\n");
else{
for(int i = 1;i <= l;++i) printf("%c", s[i]);
printf("\n");
}
return ;
}
int main(){
scanf("%s",s+1);
solve();
return 0;
}
Code 2
#include <bits/stdc++.h>
#include <cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int base1 = 13331;
const int base2 = 131;
const int mod1 = 1e9 + 7;
const int mod2 = 19260817;
const int maxn = 1e6 + 5;
ll p1[maxn],p2[maxn];
ll hash1[maxn],hash2[maxn];
int main(){
p1[0] = p2[0] = 1;for(int i = 1;i < maxn;++i) p1[i] = (p1[i-1] * base1) % mod1, p2[i] = (p2[i-1] * base2) % mod2;
string s;cin >> s;
int len = s.length();
for(int i = 1;i <= len;++i){
hash1[i] = (hash1[i-1]*base1+s[i-1])%mod1;
hash2[i] = (hash2[i-1]*base2+s[i-1])%mod2;
}
int pos = 0;
for(int i = len - 2;i >= 1;--i){
ll pre1 = hash1[i], pre2 = hash2[i];
ll suf1 = ((hash1[len] - hash1[len-i]*p1[i])%mod1+mod1)%mod1, suf2 = ((hash2[len] - hash2[len-i]*p2[i])%mod2+mod2)%mod2;
if((pre1 != suf1) || (pre2 != suf2)) continue;
for(int j = 2;j + i - 1 < len;++j){
ll h1 = ((hash1[j+i-1] - hash1[j-1]*p1[i])%mod1+mod1)%mod1, h2 = ((hash2[j+i-1] - hash2[j-1]*p2[i])%mod2+mod2)%mod2;
if((h1 == pre1) && (h2 == pre2)) {
cout << s.substr(0,i) << endl;
return 0;
}
}
}
cout << "Just a legend" << endl;
return 0;
}