CodeForces 1326D2【Manacher】

Prefix-Suffix Palindrome (Hard version)

题意:

  • 给定一个串 s s ,找出一个回文串 t t ,使得 t t = s . p r e f i x s.prefix + s . s u f f i x s.suffix ,并且 t t 的长度不大于 s s .

思路:

  • M a n a c h e r Manacher 算法中 r a d i u s [ i ] radius[ i ] 数组表示以 i i 为中心回文串半径长。那么我们如何找到前缀回文串?
  • :也就是所有 r a d i u s [ i ] = = i radius[ i ] == i 中半径最大的那个,即 m a x ( i ) max(i) . 那么 s [ 0 , r a d i u s [ i ] 1 ] s[0, radius[i]-1] 就是最长的前缀回文。

#include <bits/stdc++.h>
using namespace std;
const int maxN = 2000100;

string Manacher(string s, int len)
{
    string t = "$#";
    for(int i = 0; i < len; ++ i ) t += s[i], t += '#';
    len = t.length();
    vector<int>radius(len, 0);
    int mx = 0, id = 0;
    for(int i = 1; i < len; ++ i )
    {
        radius[i] = mx > i ? min(radius[(id << 1) - i], mx - i) : 1;
        while(i + radius[i] < len && i - radius[i] >= 0 && t[i + radius[i]] == t[i - radius[i]])
            ++ radius[i];
        if(mx < i + radius[i])
        {
            mx = i + radius[i];
            id = i;
        }
    }
    int mxLen = 0;
    for(int i = 1; i < len; ++ i )
    {
        if(radius[i] == i)
            mxLen = radius[i] - 1;
    }
    return s.substr(0, mxLen);
}

int main()
{
    int t;
    while(cin >> t)
    {
        while(t -- )
        {
            string str; cin >> str;
            string L, R;
            int len = str.length();
            for(int i = 0; i < len / 2; ++ i)
                if(str[i] == str[len - 1 - i])
                    R += str[i];
                else
                    break;
            L = R; reverse(R.begin(), R.end());
            int lenL = L.length(), lenR = lenL;
            string res = str.substr(L.length(), len - lenL - lenR);
            string res1 = Manacher(res, len - lenL - lenR);
            reverse(res.begin(), res.end());
            string res2 = Manacher(res, len - lenL - lenR);
            if(res1.length() > res2.length())
                cout << L + res1 + R << endl;
            else
                cout << L + res2 + R << endl;
        }
    }
    return 0;
}
发布了273 篇原创文章 · 获赞 76 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/104990043