题意:给一个字符串,问最长的一个子串A,他是前缀,同时是后缀,并且中间也出现过A。并且出现的三个A都不没有重叠部分。
解法:先KMP求出失配数组,然后将所有的是后缀且是前缀的打上标记,然后遍历整个next数组,(对于每个位置的next来说,一直next向前取就是找到此前缀的一个个是整个字符串前缀的后缀,比较绕)暴力枚举判断每个串的所有匹配前缀的后缀是否合法。
代码:
/****************************************************
* author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
using namespace std;
#define eps 1e-8
typedef long long LL;
int next1[1001000];
void getNext(char *s)
{
int len=strlen(s);
int i=0;
int j=next1[0]=-1;
while(i<len)
{
while(j!=-1&&s[i]!=s[j]) j=next1[j];
next1[++i]=++j;
}
}
char s[1000100];
bool rem[1000100];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(rem,0,sizeof rem);
scanf("%s",s);
getNext(s);
int len=strlen(s);
int tool=next1[len];
while(tool)
{
rem[tool]=1;
tool=next1[tool];
}
int out=0;
for(int i=len-1; i>1; i--)
{
int t=i;
while(t!=-1)
{
if(rem[next1[t]]&&len-next1[t]>=i&&i-next1[t]>=next1[t])
{
out=max(out,next1[t]);
break;
}
t=next1[t];
}
}
cout<<out<<'\n';
}
return 0;
}