回文子串的最大长度

题目描述

如果一个字符串正着读和倒着读是一样的,则称它是回文的。

给定一个长度为 \(N\) 的字符串 \(S\),求他的最长回文子串的长度是多少。

输入格式

输入将包含最多 \(30\) 个测试用例,每个测试用例占一行,以最多 \(1000000\) 个小写字符的形式给出。

输入以一个以字符串 'END' 开头的行表示输入终止。

输出格式

对于输入中的每个测试用例,输出测试用例编号和最大回文子串的长度(参考样例格式)。

每个输出占一行。

输入样例:

abcbabcbabcba
abacacbaaaab
END

输出样例:

Case 1: 13
Case 2: 6

Code:

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

typedef unsigned long long ll;

const int N=1e6+5,P=131;

int n;
char s[N<<1],st[N];
ll h[N<<1],rh[N<<1],p[N<<1];

ll get(ll h[],int l,int r)
{
    return h[r]-h[l-1]*p[r-l+1];
}
int main()
{
    int Ca=0;
    while(1)
    {
        scanf("%s",st+1);
        if(st[1]=='E')break;
        n=strlen(st+1);

        for(int i=1;i<=n;++i)
        {
            s[2*i-1]=st[i];
            s[2*i]='#';
        }
        s[2*n]='\0';
        n<<=1;

        // for(int i=1;i<=2*n;++i)
        //     putchar(s[i]);
        
        p[0]=1;h[0]=rh[0]=0;
        for(int i=1,j=n;i<=n;++i,--j)
        {
            h[i]=h[i-1]*P+s[i]-'a'+1;
            rh[i]=rh[i-1]*P+s[j]-'a'+1;
            p[i]=p[i-1]*P;
        }

        int ans=-1;
        for(int i=1;i<=n;++i)
        {
            int l=1,r=min(i,n-i+1);
            while(l<r)
            {
                int mid=(l+r+1)>>1;
                if(get(h,i-mid+1,i)==get(rh,n-(i+mid-1)+1,n-i+1))l=mid;
                else r=mid-1;
            }
            //i-l+1,i+l-1  2*l
            if(s[i-l+1]=='#')ans=max(ans,l-1);
            else ans=max(ans,l);
        }
        printf("Case %d: %d\n",++Ca,ans);
    }
    return 0;
}
posted @ 2022-10-16 20:01  FighterQ  阅读(29)  评论(0)    收藏  举报