Prefix-Suffix Palindrome (Hard version)
题意:
- 给定一个串 ,找出一个回文串 ,使得 = + ,并且 的长度不大于 .
思路:
- 算法中 数组表示以 为中心回文串半径长。那么我们如何找到前缀回文串?
- :也就是所有 中半径最大的那个,即 . 那么 就是最长的前缀回文。
#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;
}