//先开始没发现*号的作用到后面发现阔以用*号来链接就好了。
//比如fff 转换后市#*f*f*f* reall[i]表示以i为起点往右最长的回文串长度,real[i]表示以i为起点往左的最长回文串长度
//当str[i]==‘*‘;的时ans=max(ans,reall[i]/2+real[i]/2);这样从左到右枚举*就好了。
//那么怎么求reall[i] (real[i]用manacher的时候就求了)从右到左枚举以某个点位为中心的最长回文串就是下面的代码
int limitl = len - 1; reall[len - 1] = 1;
for (int i = len - 1,k=len-1; i >= 1;i--)
{
if (limitl >i - pr[i] + 1)
{
k = limitl - 1;
while (k >= i - pr[i] + 1)
{
reall[k] = max(reall[k],(i - k)*2+ 1);
k--;
}
limitl = i - pr[i] + 1;
}
}
i就代表枚举的中心点其他自己看很好懂了。pr[i]是半径.*f*那么以f为中心的最长串半径是2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
int id,len,ans;
int pr[300020];
int pl[300020];
char str[300020];
char in[200020];
int real[300020];
int reall[300020];
void manacher1()
{
pr[1] = 1; id = 1;real[0] = -1000;
//for (int i = 3; i < len; i++)
// real[i] = 1;
for (int i = 2; i < len; i++)
{
if (id + pr[id]>i)
pr[i] = min(id + pr[id] - i, pr[2 * id - i]);
else
pr[i] = 1;
while (str[i + pr[i]] == str[i - pr[i]]){real[i + pr[i]] = max(real[i + pr[i]], 2 *pr[i] + 1); pr[i]++; }
if (i + pr[i] > id + pr[id])id = i;
}
}
void getans()
{
int limitl = len - 1; reall[len - 1] = 1;
for (int i = len - 1,k=len-1; i >= 1;i--)
{
if (limitl >i - pr[i] + 1)
{
k = limitl - 1;
while (k >= i - pr[i] + 1)
{
reall[k] = max(reall[k],(i - k)*2+ 1);
k--;
}
limitl = i - pr[i] + 1;
}
}
for (int i = 2; i <= len - 2; i++)
{
if (str[i] == '*')
{
ans = max(ans, reall[i]/2 + real[i]/2);
}
}
}
int main()
{
str[0] = '#';
for (int i = 1;; i++)
{
str[i] = '*';
i++;
str[i] = getchar();
if (str[i] == '\n')
{
str[i] = '\0';
//str[i+1] = '\0';
len = i;
break;
}
}
//str[1] = '&';
//cout << str <<" "<<len<< endl;
//cout << len << endl;
if (len > 4)
{
ans = 2;
manacher1();
getans();
}
else
ans = 0;
printf("%d\n", ans);
return 0;
}