求字符串中最长回文串的长度 manacher算法 模板

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/84437630

https://www.luogu.org/problemnew/show/P3805

#include<bits/stdc++.h>
using namespace std;
const int maxn=11000002;
char S[maxn<<1];
int hw[maxn<<1];
int cnt=1,maxans=1;
inline void read()
{
    char ch=getchar();
    S[0]='~',S[1]='|';
    while(ch<'a'||ch>'z') ch=getchar();
    while(ch>='a'&&ch<='z')
	{
        S[++cnt]=ch,S[++cnt]='|';
        ch=getchar();
    }
    return;
}

void manacher()
{
	int maxright=0,mid=0;
	for (int i=1,edd=cnt;i<=edd;++i)
	{
        if(i<maxright)
            hw[i]=min(hw[(mid<<1)-i],maxright-i);
        else
            hw[i]=1;
        while(S[i-hw[i]]==S[i+hw[i]])
        //暴力拓展左右两侧,当i-p[i]==0时,由于S[0]是'~',自动停止。
        //故不会下标溢出。
            hw[i]++;
        if(hw[i]+i>maxright)
        //更新mid和maxright,保持maxright是最右的才能保证我们提前确定的部分回文半径尽量多。
            maxright=hw[i]+i,mid=i;
        if(hw[i]>maxans)
            maxans=hw[i];
    }
}

int main()
{
    read();
    manacher();
    printf("%d\n",maxans-1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/84437630