CodeForces - 1326D2 Prefix-Suffix Palindrome (Hard version) (Manacher算法)

先把两边相等的算上,然后从剩下的中间的里面找一个是前缀或者后缀的最长回文串
关于马拉车算法
Len为回文半径,MaxRight为最长回文串右端点
性质**:Len[ i ] - 1 为原串中该字母所在回文子串的长度**

int Len[MX];
string Manacher(const string & s)
{
    string str="#";
    for(char c:s) str+=c,str+="#";
    int MaxRight=0,pos=0;
    rep(i,str.size())
    {
        Len[i]=i<MaxRight?min(Len[2*pos-i],MaxRight-i+1):1;
        while(i-Len[i]>=0&&i+Len[i]<sz(str)&&str[i-Len[i]]==str[i+Len[i]]) ++Len[i];
        if(i+Len[i]-1>MaxRight)
            MaxRight=i+Len[i]-1,pos=i;
    }
    int MaxLen=0;
    rep(i,sz(str))
        if(Len[i]==i+1) MaxLen=Len[i]-1;
    return s.substr(0,MaxLen);
}
signed main()
{
    fast;
    int T;cin>>T;
    while(T--)
    {
        string s;cin>>s;
        int l=0,r=sz(s)-1;
        while(l<r&&s[l]==s[r]) ++l,--r;
        if(l>=r) cout<<s<<endl;
        else
        {
            string s1=s.substr(l,r-l+1);
            string s2(s1);
            reverse(s2.begin(),s2.end());
            s1=Manacher(s1);
            s2=Manacher(s2);
            cout<<s.substr(0,l)<<(sz(s1)>sz(s2)?s1:s2)<<s.substr(r+1)<<endl;
        }
        
    }
    return 0;
}

你可能感兴趣的:(字符串---Manacher)