题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2084
首先一个反对称其实就是在原串上的回文,只不过回文相等的判断要修改成:
然后跑一遍Manacher,最后注意$ans+=p_idiv 2$就是“回文”的总数(注意有不饱和回文串)。
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=500050; 7 8 int p[N*2]; 9 char str[N],s[N*2]; 10 int ans,t; 11 12 bool cmp(char a,char b){ 13 return (a=='#'&&b=='#')||((a^b)==1); 14 } 15 16 void manacher(int len){ 17 s[0]='$';s[++t]='#'; 18 for(int i=1;i<=len;i++){ 19 s[++t]=str[i]; 20 s[++t]='#'; 21 } 22 int pos=0,mx=0; 23 for(int i=1;i<=t;i++){ 24 if(i>mx) p[i]=1; 25 else p[i]=min(mx-i,p[2*pos-i]); 26 while(i+p[i]<=t&&i-p[i]>=1&&cmp(s[i+p[i]],s[i-p[i]])) p[i]++; 27 if(i+p[i]>mx){ 28 mx=i+p[i]; 29 pos=i; 30 } 31 ans+=p[i]/2; 32 } 33 } 34 35 int main(){ 36 int n; 37 scanf("%d",&n); 38 scanf("%s",str+1); 39 manacher(n); 40 printf("%d ",ans); 41 return 0; 42 }