BZOJ 2084 [Poi2010]Antisymmetry(Manacher)

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2084

 

首先一个反对称其实就是在原串上的回文,只不过回文相等的判断要修改成:

 

然后跑一遍Manacher,最后注意$ans+=p_i\div 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\n",ans);
41     return 0;
42 }
AC代码

 

posted @ 2020-02-20 20:17  dfydn  阅读(144)  评论(0)    收藏  举报