H - Prefix-Suffix Palindrome (Hard version) CodeForces - 1326D2(马拉车)

H - Prefix-Suffix Palindrome (Hard version) CodeForces - 1326D2

Title link

Ideas

  • Analysis: First, match the strings one by one before and after, take out the rest of the match and run to the side of the Manacher (note the size of the array of strings, because it is really T to vomit blood during the game )

Code

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
void fre() { freopen("A.txt","r",stdin); freopen("Ans.txt","w",stdout); }
const int mxn = 5e6 + 10;

char ar[mxn], br[mxn], cr[mxn];
int len[mxn];
int is_front;

int trans(int lbr)
{
    int cnt = 0;
    cr[cnt ++] = '$';
    for(int i = 1; i <= lbr; i ++)
    {
        cr[cnt ++] = '#';
        cr[cnt ++] = br[i];
    }
    cr[cnt ++] = '#';
    cr[cnt] = '%';
    return cnt;
}

int Manacher(int lcr)
{
    int mid = 0, mr = 0;
    int mx = 0;
    for(int i = 1; i < lcr; i ++)
    {
        if(i < mr) len[i] = min(mr - i, len[2*mid - i]);
        else len[i] = 1;
        while(cr[i - len[i]] == cr[i + len[i]]) len[i] ++;
        if(mr < i + len[i])
        {
            mr = i + len[i];
            mid = i;
        }
        if(mx < len[i] && (i - len[i] == 0 || i + len[i] == lcr))
        {
            mx = len[i];
            if(i - len[i] == 0)
                is_front = 1;
            else 
                is_front = 0;
        }
    }
    return mx - 1;
}



int main()
{
    /* fre(); */
    int t;
    scanf("%d", &t);
    while(t --)
    {
        memset(len, 0, sizeof(0));
        scanf("%s", ar + 1);
        int lar = strlen(ar + 1);
        int l = 1, r = lar;
        while(l < r && ar[l] == ar[r])
            l ++, r --;
        int lbr = 0;
        for(int i = l; i <= r; i ++)
            br[++ lbr] = ar[i];
        int mx = Manacher(trans(lbr));
        for(int i = 1; i < l; i ++)
            printf("%c", ar[i]);
        if(is_front)
        {
            for(int i = 1; i <= mx; i ++)
                printf("%c", br[i]);
        }
        else
        {
            for(int i = lbr - mx + 1; i <= lbr; i ++)
                printf("%c", br[i]);
        }

        for(int i = r + 1; i <= lar; i ++)
            printf("%c", ar[i]);
        printf("\n");
    }

    return 0;
}

Guess you like

Origin www.cnblogs.com/lql-nyist/p/12735742.html