Manacher(马拉车)--最长回文子串

//洛谷https://www.luogu.com.cn/problem/P3805
int d[22000007];  //二倍长度
char s[22000007];
int k=0,len,maxn=INT_MIN;
void manacher(char s[]){            //复杂度o(n)
    d[1]=1;
    for(int i=2,l=2,r=1;i<=k;i++){
        if(l<=r) d[i]=min(d[l+r-i],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; //如果右边界超出当前盒子的右边界,更新盒子左右边界
        maxn=max(maxn,d[i]);
    }
}

void strInit(string str){       //根据原字符串str,创建一个新字符串,存到s数组中
    s[0]='$',s[++k]='#';
    for(int i=0;i<len;i++){
        s[++k]=str[i];
        s[++k]='#';
    }
}

void solve(){
    string str;
    cin>>str;
    len=str.size();
    strInit(str);
    manacher(s);
    cout<<maxn-1<<"\n";   //原串最长回文子串=新串最长回文半径-1
}

posted @ 2023-12-13 13:14  osir  阅读(0)  评论(0编辑  收藏  举报