F05【模板】Manacher 算法

F05 Manacher(马拉车)_哔哩哔哩_bilibili

 

P3805 【模板】manacher - 洛谷

题目:给一个字符串 S,求 S 中最长回文串的长度

用特殊字符花插字符串,双指针预处理回文半径函数,选取最大值

// Manacher O(n)
#include<bits/stdc++.h>
using namespace std;

const int N=3e7;
char a[N],s[N];
int d[N]; //回文半径函数 

void get_d(char*s,int n){ //d函数
  d[1]=1;
  for(int i=2,l,r=1;i<=n;i++){
    if(i<=r) d[i]=min(d[r-i+l],r-i+1);
    while(s[i-d[i]]==s[i+d[i]]) d[i]++;
    if(i+d[i]-1>r) l=i-d[i]+1,r=i+d[i]-1;
  }  
}
int main(){
  scanf("%s",a+1);
  int n=strlen(a+1),k=0;
  s[0]='$',s[++k]='#';
  for(int i=1;i<=n;i++) s[++k]=a[i],s[++k]='#';
  n=k;
  
  get_d(s,n);
  int ans=0;
  for(int i=1;i<=n;i++) ans=max(ans,d[i]);
  printf("%d\n",ans-1);
  return 0;
}

 

// 哈希法 O(n)
#include<bits/stdc++.h>
using namespace std;

typedef unsigned long long ull;
const int N=1.1e7+5;
const int B=131;
int n,r[N],ans;
string s;
ull f[N],g[N],b[N];

ull get1(int l,int r){
  return f[r]-f[l-1]*b[r-l+1];
}
ull get2(int l,int r){
  return g[l]-g[r+1]*b[r-l+1];
}
signed main(){
  ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);
  cin>>s; n=s.size(); s=" "+s;
  b[0]=1;
  for(int i=1; i<=n; i++){
    f[i]=f[i-1]*B+s[i];
    b[i]=b[i-1]*B;
  }
  for(int i=n; i>=1; i--) g[i]=g[i+1]*B+s[i];
  
  for(int i=1,j=1; i<=n; i++){
    if(j!=1) j--;
    while(j<i){
      int len=(i-j+1)/2;
      if(get2(j,j+len-1)==get1(i-len+1,i)) break;
      j++;
    }
    ans=max(ans,i-j+1);
  }
  cout<<ans<<'\n';
  return 0;
}

 

P3501 [POI 2010] ANT-Antisymmetry - 洛谷

 

posted @ 2022-04-14 08:53  董晓  阅读(1810)  评论(0)    收藏  举报