QDU 10-LC和加玛帝国的公主-回文子串线性筛-模板

题目描述:

有一天, 我们帅气的LC来到加玛帝国. 有时候, 缘分就是这么奇怪, LC和加玛帝国的公主一见钟情, 奈何公主的父王不同意, 因为他觉得LC除了长得特别帅之外, 并没有一技之长.

LC对此呵呵一笑, 他说, 我可是创新实验室走出来的学生, 我会的技能可多着呢, 先说个简单的吧, 只要你给我任意一串字符串, 我就能立马算出这串字符串当中最长回文串的长度. 国王很是吃惊, 说要考一考LC.

于是国王想让你帮忙写一个程序, 用来比对LC的答案, 快来帮帮国王吧!

输入描述:

第一行输入一个T(T <= 50), 表示一共有T组测试数据. 接下来T行, 每行为一组由小写字母组成, 长度不超过10^5的字符串.

输出描述:

每行一个整数X, 表示该组字符串中所包含的最长回文长度.

输入样例:

3
aba
abc
aabaa

输出样例:

3
1
5

核心思想:

回文子串线性筛。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e6+10;
char s[N],ss[N];
int p[N];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        scanf("%s",ss);
        int k=2,id=0,mx=0,len=strlen(ss);
        char c;
        s[0]='$'; s[1]='#';
        for(int i=0;i<len;i++)
        {
            c=ss[i];
            s[k++]=c;
            s[k++]='#';
        }
        p[0]=1;	p[1]=1;
        for(int i=2;i<k;i++)
        {//若s[i]在以id为中心,以mx(不含mx)为边的大回文中,p[i]初始化,确保p[i]只走一遍
            //cout<<s[i]<<' ';
            if(i<mx)
                p[i]=min(p[2*id-i],mx-i);
            else
                p[i]=1;
            while(s[i-p[i]]==s[i+p[i]])p[i]++;
            if(i+p[i]>mx)//更新mx和id,大回文更新
            {
                mx=i+p[i];
                id=i;
            }
        }
        int ans=0;
        for(int i=0;i<k;i++)
        {
            //cout<<p[i]<<' ';
            ans=max(ans,p[i]);
        }
        //cout<<endl;
        printf("%d\n",ans-1);
        }
    return 0;
}
发布了144 篇原创文章 · 获赞 135 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Nothing_but_Fight/article/details/102372496