1. 程式人生 > 實用技巧 >HDU 3068 最長迴文 (馬拉車板子)

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;
}