Manacher算法
模板:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//变量初始化
//--------------------------
const int maxn=2000006;
char p[maxn],s[2*maxn];
int len[2*maxn];
//--------------------------
//马拉车算法主体
//---------------------------------------------
int init(char *str,char *s)
{
int n=strlen(str);
for(int i=1,j=0;i<=2*n;j++,i+=2)
{
s[i]='#';
s[i+1]=str[j];
}
s[0]='$';
s[2*n+1]='#';
s[2*n+2]='@';
s[2*n+3]='\n';
return 2*n+1;
}
void manacher(int n,char *s,int *len)
{
int mx=0,p=0;
for(int i=1;i<=n;i++)
{
if(mx>i)len[i]=min(mx-i,len[2*p-i]);
else len[i]=1;
while(s[i-len[i]]==s[i+len[i]])len[i]++;
if(len[i]+i>mx)mx=len[i]+i,p=i;
}
}
//------------------------------------------------
//求回文子串数量
ll countSubstrings(char *p,char *s,int *len)
{
int n=init(p,s);
for(int i = 0; i < n; ++i)
len[i]=0;
manacher(n,s,len);
ll ans=0;
for(int i=1;i<=n;i++)
ans+=len[i]/2;
return ans;
}
//求最长回文子串长度
int maxLength(char *p,char *s,int *len)
{
int n=init(p,s);
for(int i = 0; i < n; ++i)
len[i]=0;
manacher(n,s,len);
int maxLen = -1;
for(int i=1;i<=n;i++)
maxLen=max(maxLen,len[i]);
return maxLen-1;
}
int main()
{
scanf("%s",p);
ll ans = countSubstrings(p,s,len);
printf("%lld\n",ans);
return 0;
}