Codeforces Global Round 7 D2 - Prefix-Suffix Palindrome (Hard version)

D2. Prefix-Suffix Palindrome (Hard version)

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

This is the hard version of the problem. The difference is the constraint on the sum of lengths of strings and the number of test cases. You can make hacks only if you solve all versions of this task.

You are given a string ss, consisting of lowercase English letters. Find the longest string, tt, which satisfies the following conditions:

  • The length of tt does not exceed the length of ss.
  • tt is a palindrome.
  • There exists two strings aa and bb (possibly empty), such that t=a+bt=a+b ( "++" represents concatenation), and aa is prefix of ss while bb is suffix of ss.

Input

The input consists of multiple test cases. The first line contains a single integer tt (1≤t≤1051≤t≤105), the number of test cases. The next tt lines each describe a test case.

Each test case is a non-empty string ss, consisting of lowercase English letters.

It is guaranteed that the sum of lengths of strings over all test cases does not exceed 106106.

Output

For each test case, print the longest string which satisfies the conditions described above. If there exists multiple possible solutions, print any of them.

Example

input

Copy

5
a
abcdfdcecba
abbaxyzyx
codeforces
acbba

output

Copy

a
abcdfdcba
xyzyx
c
abba

Note

In the first test, the string s=s="a" satisfies all conditions.

In the second test, the string "abcdfdcba" satisfies all conditions, because:

  • Its length is 99, which does not exceed the length of the string ss, which equals 1111.
  • It is a palindrome.
  • "abcdfdcba" == "abcdfdc" ++ "ba", and "abcdfdc" is a prefix of ss while "ba" is a suffix of ss.

It can be proven that there does not exist a longer string which satisfies the conditions.

In the fourth test, the string "c" is correct, because "c" == "c" ++ "" and aa or bb can be empty. The other possible solution for this test is "s".

思路:

前缀回文为a,后缀回文为b,不管a或者b谁为空,首先对原始字符串进行manacher算法处理,当然中间要进行处理,找到最长前缀回文串的长度和最长后缀回文串的长度;并且比较两者长度,将较长的一个作为答案的一部分;

如果a,b都不为空,那么双指针往中间缩动;找到之间不能匹配的一段字符串,然后对其进行manacher算法处理;和上面一样求出长前缀回文串的长度和最长后缀回文串的长度;作为答案的中间的一部分;

#include<bits/stdc++.h>
using namespace std;
const int maxx = 3e6+10;
char tmp[maxx];
int len[maxx];
int s1,s2;
void Manacher(string s)
{
    tmp[0]='$';
    tmp[1]='#';
    int t=s.size();
    for(int i=0;i<2*t+5;i++)len[i]=0;
    for(int i=1;i<=t;i++)
    {
        tmp[2*i]=s[i-1];
        tmp[2*i+1]='#';
    }
    tmp[2*t+2]='\0';
    int mx=0;
    int mid;
    for(int i=1;tmp[i];i++)
    {
        if(i<mx)len[i]=min(len[2*mid-i],mx-i);
        else len[i]=1;
        while(tmp[i-len[i]]==tmp[i+len[i]])len[i]++;
        if(len[i]+i>mx)
        {
            mx=len[i]+i;
            mid=i;
        }
        int l=len[i]-1;
        if(i%2==0)
        {
            l=(l-1)/2;
            int p=i/2;
            if(p-l==1)s1=max(s1,len[i]-1);
            if(p+l==t)s2=max(s2,len[i]-1);
        }
        else
        {
            l=l/2;
            int p=(i-1)/2,q=(i+1)/2;
            if(p-l+1==1)s1=max(s1,len[i]-1);
            if(q+l-1==t)s2=max(s2,len[i]-1);
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        s1=0,s2=0;
        string s,ans1,ans2;
        cin>>s;
        int n=s.size();
        Manacher(s);
        if(s1>s2) ans1=s.substr(0,s1);
        else ans1=s.substr(n-s2,s2);
        int i=0,j=n-1;
        while(i<j&&s[i]==s[j]) ans2+=s[i],i++,j--;
        string ss=s;
        if(i<j)
        {
            s1=0,s2=0;
            ss=s.substr(i,j-i+1);
            int n=ss.size();
            Manacher(ss);
            if(s1>s2) ans2+=ss.substr(0,s1);
            else ans2+=ss.substr(n-s2,s2);
        }
        ans2+=s.substr(j+1);
        if(ans1.size()>=ans2.size()) cout<<ans1<<endl;
        else cout<<ans2<<endl;
    }
    return 0;
}
发布了221 篇原创文章 · 获赞 54 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_43872728/article/details/104998665