Codeforces 1326D2 - Prefix-Suffix Palindrome 马拉车

几个月没写马拉车了,比赛的时候调了半天,代码也写的极丑


题意:

给你字符串s,让你找到一个最长的回文串a+b,字符串a为s的前缀,b为s的后缀

题解:

先对s做一遍马拉车

细分有四种情况:

1.b为空,即最长的回文串就是某前缀,代码中该长度记为le

2.a为空,即最长的回文串就是某后缀,代码中该长度记为ri

3.a>=b,a的前b个字符与b对应为回文串,a串后(a-b)为回文串。代码中old=min(a,b),tmp=max(a,b)-min(a,b)

4.a

注意下细节,边界情况的考虑。为了简单计算,在马拉车过后的Mp[]数组上进行分析

#include 
using namespace std;
typedef long long ll;
const int maxn=1000050;
char Ma[maxn*2];
int Mp[maxn*2];
int Manacher(char s[],int len)
{
    int l = 0;
    Ma[l++] = '$';
    Ma[l++] = '#';
    for(int i = 0; ii ? min(Mp[2*id-i],mx-i) : 1;
        while(i-Mp[i]>=0 && Ma[i+Mp[i]]==Ma[i-Mp[i]]) Mp[i]++;
        if(i+Mp[i]>mx)
        {
            mx=i+Mp[i];
            id=i;
        }
    }
    return l;
}

char s[maxn];
int p[maxn];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%s",s);
        int slen = strlen(s);
        if(slen==1){
            printf("%s\n",s);
            continue;
        }
        int len = Manacher(s,slen),old=0;
        int le=0,ri=0,l=0,r=slen-1,n=slen*2;
        for(int i = 2; i=n){
                ri=max(ri,Mp[i]-1);
            }
        }
        while(l=r){
                    printf("%s",s);
                    break;
                }
            }
            else{
                int tmp=0,flag=0;
                l=2*(l+1);r=2*(r+1);
                for(int i = 2; iR) continue;
                    if(L<=l&&i-l<=r-i&&(i-l+1)>tmp){
                        tmp=(i-l+1);
                        flag=0;
                    }
                    if(R>=r&&i-l>=r-i&&(r-i+1)>tmp){
                        tmp=(r-i+1);
                        flag=1;
                    }
                }
                if(tmp+old*2>max(le,ri)){
                    if(flag){
                        for(int i=0;iri) for(int i=0;i

 

你可能感兴趣的:(Codeforces,字符串)