统计最长回文串(传说中的Manacher算法)Hihocoder 1032

算法的核心就在这一句上了:p[i] = min(p[2*id-i], p[id] + id - i);

 


#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <fstream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <iomanip> using namespace std; const int N=1000010; /*int len;            //原串长 char str[N];        //接收原来的串 char s[N*2];        //做了插入处理的结果串 int P[N*2];         //保存关于长度的信息(回文长度的一半再加1) int cal() {     int id=1, mx=1, max1=1;     P[0]=1;     P[1]=1;     for(int i=2; s[i]!='\0'; i++)        //考虑以i为中心的回文串     {         P[i] =i>mx? 1: min( P[2*id-i],mx-i);         while(s[i+P[i]]==s[i-P[i]])     //在这比对             P[i]++;         if(i+P[i]>mx)       //更新id和mx的位置         {             id=i;             mx=i+P[i];         }         if(P[i]-1>max1)     //更新最大值             max1=P[i]-1;     }     return max1; } int main() {     int t;     cin>>t;     while(t--)     {         scanf("%s",str);         len=strlen(str);         memset(s,0,sizeof(s));         memset(P,0,sizeof(P));                  //插入符号#         s[0]='$';         s[1]='#';         int i=0, j=2;         for(; i<len; i++)         {             s[j++]=str[i];             s[j++]='#';         }         cout<<cal()<<endl;     }     return 0; } */ int Manacher(string &str, int len) {     //插上辅助字符#     string tmp(len*2+2,'#');     tmp[0]='$';     for(int i=0; i<str.size(); i++)    tmp[i*2+2]=str[i];          int ans=1;     int mx=1, id=1;     vector<int> P(2*len+2,0);          for(int i=2; i<tmp.size(); i++)     {         P[i]=( i>=mx? 1: min( P[2*id-i], mx-i ));         while( tmp[i-P[i]]==tmp[i+P[i]] )    P[i]++;    //匹配了就继续扩大P[i]                  if(mx<=i+P[i])//重要:更新位置         {             mx=i+P[i];             id=i;         }         ans=max(ans, P[i]-1); //这就是长度了,不信动手画。     }     return ans; } int main() {     int t;     string str;     cin>>t;     while(t--)     {         cin>>str;         cout<<Manacher(str, str.size())<<endl;;     }     return 0; }

 

posted @ 2018-08-01 14:04  小学弟-  阅读(129)  评论(0编辑  收藏  举报