求输入的每一个字符串中的最长回文串的长度
最长子串的长度是半径减1,起始位置是中间位置减去半径再除以2。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
int len[3*maxn];
char s[maxn],str[3*maxn];
int slen,id,n,mx; //mx是上一次操作的最长回文子串的最右端
void init() //id记录最长回文子串的中点在字符串的下标
{
int k = 0;
str[k++] = '$';
for(int i=0;i<slen;i++)
{
str[k++] = '#';
str[k++] = s[i];
}
str[k++] = '#';
slen = k;
}
int Manacher()
{
len[0] = 0;
int sum = 0;
mx = 0;
for(int i=1;i<slen;i++)
{
if(i < mx)
len[i] = min(mx-i,len[2*id-i]);
else
len[i] = 1;
while(str[i-len[i]]==str[i+len[i]])
len[i]++;
if(len[i]+i > mx)
{
mx = len[i]+i;
id = i;
sum = max(sum,len[i]);
}
}
return sum-1;
}
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%s",s);
memset(str,0,sizeof(str));
slen = strlen(s);
init();
int ans = Manacher();
printf("%d\n",ans);
}
return 0;
}