zstu-3769 数回文子串

时间:2023-03-09 18:54:11
zstu-3769 数回文子串

思路:用manacher求出每个位置的半径,相加即可。

代码:【rad[i]/2】即i这个位置的回文半径,添加的'#'代表长度为偶数的串。

 #include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int N=1e5+;
char s[N],cpy[N<<];
int rad[N<<];
void manacher(char *s,int len,int rad[])
{
for(int i=,j=,k;i<len;i+=k)
{
while(s[i-j-]==s[i+j+]) j++;
rad[i]=j;
for(k=;k<=rad[i]&&rad[i-k]!=rad[i]-k;k++)
rad[i+k]=min(rad[i]-k,rad[i-k]);
j=max(j-k,);
}
}
void work(char *s,int rad[])
{
int len=strlen(s);
cpy[]='(',cpy[]='#';
for(int i=,j=;i<len;i++,j+=)
{
cpy[j]=s[i];
cpy[j+]='#';
}
cpy[(len=len*+)-]=')';
manacher(cpy,len,rad);
int ans=;
for(int i=;i<len;i++)
ans+=rad[i]/;
printf("%d\n",ans);
}
int main()
{
while(scanf("%s",s)!=EOF)
{
work(s,rad);
}
return ;
}