马拉车算法,统计字符串中最长的回文子串的数量
AcWing 3188. manacher算法
#include<bits/stdc++.h>
using namespace std;
const int N = 2e7 + 10;
int n;
char a[N], b[N];
int p[N];
int ans;
void init(){
int k = 0;
b[k ++ ] = '$', b[k ++ ] = '#';
for(int i = 0; i < n; i ++ ){
b[k ++ ] = a[i], b[k ++ ] = '#';
}
b[k ++ ] = '^';
n = k;
}
void manacher()
{
int mr = 0, mid;
for(int i = 1; i < n; i ++ ){
if(i < mr) p[i] = min(p[2 * mid - i], mr - i); //mr是开区间,所以不用mr-i+1
else p[i] = 1;
while(b[i - p[i]] == b[i + p[i]]) p[i] ++ ;
if(i + p[i] > mr){
mr = i + p[i]; //p[i]已经++,此时b[i+p[i]]应该是!=b[i-p[i]]mr取的闭区间
mid = i;
}
}
}
int main()
{
scanf("%s", a);
n = strlen(a);
init();
manacher();
for(int i = 0; i < n; i ++ ) ans = max(ans, p[i]);
ans -- ;
cout<<ans<<endl;
return 0;
}