#include<bits/stdc++.h>
using namespace std;
string transform(string& s) {
string ret;
ret.push_back('^');
for(int i=0;i<s.size();i++) {
ret.push_back(s[i]);
if(i+1<s.size()) ret.push_back('_');
}
ret.push_back('$');
return ret;
}
string longest(string& _s) {
string s = transform(_s); // transform string to ^a_a_b_b_a_a$ so every palindrome is odd length
int n = s.size();
int best=0;
vector<int> pal(n,0);
int l=1,r=1; // rightmost palindrome atm
for(int i = 1; i < n-1; i++) {
pal[i] = min(pal[l+(r - i)], r - i); // set palindrome (half) length at center i to the mirrored string's length (capped at r)
while(s[i - pal[i]] == s[i + pal[i]]) pal[i]++; // increase palindrome length if possible
if(i + pal[i] > r) {
// update rightmost palindrome end
l = i - pal[i];
r = i + pal[i];
}
// update best palindrome
if(pal[i] >= pal[best]) best = i;
}
string ans = "";
for(int i=best-pal[best]+1;i<best+pal[best];i++) if(s[i] != '_') ans.push_back(s[i]);
return ans;
}
string longest(vector<string>& str) {
string best;
for(auto& s : str) {
auto ss = longest(s);
cout<<ss<<endl;
if(ss.size() > best.size()) best = ss;
}
return best;
}
int main() {
vector<string> v = {"carracecar", "aabbaa", "aabbbabab"};
cout<<longest(v)<<endl;
}
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cmluZyB0cmFuc2Zvcm0oc3RyaW5nJiBzKSB7CiAgICBzdHJpbmcgcmV0OwogICAgcmV0LnB1c2hfYmFjaygnXicpOwogICAgZm9yKGludCBpPTA7aTxzLnNpemUoKTtpKyspIHsKICAgICAgICByZXQucHVzaF9iYWNrKHNbaV0pOwogICAgICAgIGlmKGkrMTxzLnNpemUoKSkgcmV0LnB1c2hfYmFjaygnXycpOwogICAgfQogICAgcmV0LnB1c2hfYmFjaygnJCcpOwogICAgcmV0dXJuIHJldDsKfQoKc3RyaW5nIGxvbmdlc3Qoc3RyaW5nJiBfcykgewogICAgc3RyaW5nIHMgPSB0cmFuc2Zvcm0oX3MpOyAvLyB0cmFuc2Zvcm0gc3RyaW5nIHRvIF5hX2FfYl9iX2FfYSQgc28gZXZlcnkgcGFsaW5kcm9tZSBpcyBvZGQgbGVuZ3RoCiAgICBpbnQgbiA9IHMuc2l6ZSgpOwogICAgaW50IGJlc3Q9MDsKICAgIHZlY3RvcjxpbnQ+IHBhbChuLDApOwogICAgaW50IGw9MSxyPTE7IC8vIHJpZ2h0bW9zdCBwYWxpbmRyb21lIGF0bQogICAgZm9yKGludCBpID0gMTsgaSA8IG4tMTsgaSsrKSB7CiAgICAgICAgcGFsW2ldID0gbWluKHBhbFtsKyhyIC0gaSldLCByIC0gaSk7IC8vIHNldCBwYWxpbmRyb21lIChoYWxmKSBsZW5ndGggYXQgY2VudGVyIGkgdG8gdGhlIG1pcnJvcmVkIHN0cmluZydzIGxlbmd0aCAoY2FwcGVkIGF0IHIpCiAgICAgICAgd2hpbGUoc1tpIC0gcGFsW2ldXSA9PSBzW2kgKyBwYWxbaV1dKSBwYWxbaV0rKzsgLy8gaW5jcmVhc2UgcGFsaW5kcm9tZSBsZW5ndGggaWYgcG9zc2libGUKICAgICAgICBpZihpICsgcGFsW2ldID4gcikgewogICAgICAgICAgICAvLyB1cGRhdGUgcmlnaHRtb3N0IHBhbGluZHJvbWUgZW5kCiAgICAgICAgICAgIGwgPSBpIC0gcGFsW2ldOwogICAgICAgICAgICByID0gaSArIHBhbFtpXTsKICAgICAgICB9CiAgICAgICAgLy8gdXBkYXRlIGJlc3QgcGFsaW5kcm9tZQogICAgICAgIGlmKHBhbFtpXSA+PSBwYWxbYmVzdF0pIGJlc3QgPSBpOwogICAgfQogICAgc3RyaW5nIGFucyA9ICIiOwogICAgZm9yKGludCBpPWJlc3QtcGFsW2Jlc3RdKzE7aTxiZXN0K3BhbFtiZXN0XTtpKyspIGlmKHNbaV0gIT0gJ18nKSBhbnMucHVzaF9iYWNrKHNbaV0pOwogICAgcmV0dXJuIGFuczsKfQoKc3RyaW5nIGxvbmdlc3QodmVjdG9yPHN0cmluZz4mIHN0cikgewogICAgc3RyaW5nIGJlc3Q7CiAgICBmb3IoYXV0byYgcyA6IHN0cikgewogICAgICAgIGF1dG8gc3MgPSBsb25nZXN0KHMpOwogICAgICAgIGNvdXQ8PHNzPDxlbmRsOwogICAgICAgIGlmKHNzLnNpemUoKSA+IGJlc3Quc2l6ZSgpKSBiZXN0ID0gc3M7CiAgICB9CiAgICByZXR1cm4gYmVzdDsKfQoKaW50IG1haW4oKSB7CiAgICB2ZWN0b3I8c3RyaW5nPiB2ID0geyJjYXJyYWNlY2FyIiwgImFhYmJhYSIsICJhYWJiYmFiYWIifTsKICAgIGNvdXQ8PGxvbmdlc3Qodik8PGVuZGw7Cn0K