Prefix-Suffix Palindrome

D2. Prefix-Suffix Palindrome (Hard version)

参考:Codeforces Global Round 7 — Editorial

关键在于会利用马拉车算法求最长回文串。

// Created by CAD on 2020/5/14.
#include <bits/stdc++.h>
using namespace std;

const int maxn=1e6+5;
int d1[maxn],d2[maxn];
string manacher(string &s){
    //回文串的长为 2*d1[i]-1,2*d2[i]
    int n=s.size();
    bool bj=0;
    int ans=0;
    for(int i=0,l=0,r=-1;i<n;++i){
        int k=(i>r)?1:min(d1[l+r-i],r-i);
        while(0<=i-k&&i+k<n&&s[i-k]==s[i+k])
            k++;
        if(i-k+1==0&&2*k-1>ans) ans=2*k-1,bj=0;
        if(i+k==n&&2*k-1>ans) bj=1,ans=2*k-1;
        d1[i]=k--;
        if(i+k>r)
            l=i-k,r=i+k;
    }
    for(int i=0,l=0,r=-1;i<n;++i){
        int k=(i>r)?0:min(d2[l+r-i+1],r-i+1);
        while(0<=i-k-1&&i+k<n&&s[i-k-1]==s[i+k])
            k++;
        if(i-k==0&&2*k>ans) bj=0,ans=2*k;
        if(i+k==n&&2*k>ans) bj=1,ans=2*k;
        d2[i]=k--;
        if(i+k>r)
            l=i-k-1,r=i+k;
    }
    return bj?s.substr(n-ans):s.substr(0,ans);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;cin>>t;
    while (t--){
        string s;cin>>s;
        string s1=s;
        reverse(s1.begin(),s1.end());
        int ans=0,n=s.size();
        while(ans<n/2&&s[ans]==s1[ans]) ans++;
        string str=s.substr(ans,n-2*ans);
        cout<<s.substr(0,ans)<<manacher(str)<<s.substr(n-ans)<<"\n";
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/CADCADCAD/p/12893911.html