manacher模板

本文仅是记录manacher算法的一个模板,并不对算法进行详细讲解

代码中的p数组表示以第i个点为中心所能扩展到的最长回文串,在新的串中首尾加一个不同字符可以防止其无限扩展,对于代码中的p[i]=min(p[id*2-i],maxn-i)表示因为id的左右是回文的所以对称,这里是求现在以i为中心,在目前所能扩展到底最远的范围内最长回文串的长度,之后进行暴力更新,不难得复杂度是O(n)

代码(hdu3068

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
char s1[310000],s2[310000];
int len1,len2,p[310000];
void init(){
      s2[0]='#';
      s2[1]='$';
      for(int i=0;i<len1;i++){
         s2[i*2+2]=s1[i];
         s2[i*2+3]='$';
      }
      len2=len1*2+2;
      s2[len2]='@';
}
void horsewithcar(){
      int id=0,maxn=0;
      for(int i=1;i<len2;i++){
           if(maxn>i)p[i]=min(p[id*2-i],maxn-i);
             else p[i]=1;
           for(;s2[i+p[i]]==s2[i-p[i]];p[i]++)
              if(i+p[i]>maxn){
                  maxn=i+p[i];
                  id=i;
              }
      }
}
int main()
{     int n,m,i,j,k;
      while(scanf("%s",s1)!=EOF){//我也不知道为啥hdu上不加!=EOF会tle
          len1=strlen(s1);
          init();
          horsewithcar();
          int ans=0;
          for(i=1;i<len2;i++)
             ans=max(ans,p[i]);
          cout<<ans-1<<endl;
      }
      return 0;
}

posted @ 2018-05-15 10:11  水题收割者  阅读(99)  评论(0编辑  收藏  举报