HDU 3068 最长回文 (马拉车板子)

题目

给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等

思路

马拉车。马拉车的核心思想就是通过前面已经匹配了的回文串和其对称性来快速计算右半边的p数组值,这样就省去了多次中心扩展的次数,从而降低了时间复杂度。那么加上#号的操作是为了统一奇偶回文的情况,利于统一实现。

code

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&-x
typedef long long ll;
typedef pair<int,int> PII;
void check_max (int &a,int b) {a=max (a,b);}
void check_min (int &a,int b) {a=min (a,b);}
const int maxn=1e6+10;
int a[maxn];
string str;
// vector <int> p (2*maxn,0);

string Manacher (string s) {
   string st="@#";
   for (int i=0;i<s.size ();i++) st+=s[i],st+="#";
   vector <int> p (st.size (),0);
   int mx=0,id=0,ans=0,center=0;
   for (int i=1;i<p.size ();i++) {
      p[i]=mx>i?min (p[2*id-i],mx-i):1;
      while (st[i+p[i]]==st[i-p[i]]) p[i]++;
      if (mx<i+p[i]) {
         mx=i+p[i];
         id=i;
      }
      if (ans<p[i]) {
         check_max (ans,p[i]);
         center=i;
      }
   }
   return s.substr ((center-ans)/2,ans-1);
}

int main () {
   ios::sync_with_stdio (false);   
   while (cin>>str) {
      cout<<Manacher (str).size ()<<endl;
   }
   return 0;
}
posted @ 2020-12-01 10:46  Luglucky  阅读(81)  评论(0编辑  收藏  举报