Manacher(马拉车):字符串中最长回文子串长度

一、模板

#include 
#include 
#include 
#define M 10000010
using namespace std;
char str[M],StrNew[2*M];
int p[2*M],len;
void init()
{
    int i;
    len=strlen(str);
    StrNew[0]='@';
    StrNew[1]='#';
    for(i=0;i<len;i++)
    {
        StrNew[i*2+2]=str[i];
        StrNew[i*2+3]='#';
    }
    StrNew[len*2+2]='$';
}
void Manacher()
{
    memset(p,0,sizeof(p));
    int mx=0,di,ans=0,i;
    for(i=1;i<len*2+2;i++)
    {
        if(mx>i)
            p[i]=min(mx-i,p[di*2-i]);
        else p[i]=1;
        for(;StrNew[i-p[i]]==StrNew[i+p[i]];p[i]++);
        if(p[i]+i>mx)
        {
            mx=p[i]+i;
            di=i;
        }
        ans=max(ans,p[i]);
    }
    cout<<--ans<<endl;
}
int main()
{
    cin>>str;
    init();
    Manacher();
    return 0;
}

二、Best Reward

题目:acm.hdu.edu.cn/showproblem.php?pid=3613
Manacher(马拉车):字符串中最长回文子串长度_第1张图片
代码:

#include 
#include 
#include 
#define mem(a) memset(a,0,sizeof(a) )
using namespace std;
typedef long long ll;
const int maxn=500050;
char str[maxn],StrNew[maxn*2];
int p[maxn*2],sum[maxn],w[50];
int init()
{
    int len=strlen(str);
    StrNew[0]='@';
    StrNew[1]='#';
    int i,j=2;
    for(i=0;i<len;i++)
    {
        StrNew[j++]=str[i];
        StrNew[j++]='#';
    }
    StrNew[j]='$';
    return j;
}
void Manacher()
{
    int len=init();
    int id,mx=0,i;
    for(i=1;i<len;i++)
    {
        if(mx>i) p[i]=min(mx-i,p[id*2-i]);
        else p[i]=1;
        for(;StrNew[i+p[i]]==StrNew[i-p[i]];p[i]++);
        if(mx>p[i]+i) mx=p[i]+i,id=i;
    }
    return;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        mem(p);
        int i;
        for(i=0;i<26;i++)
            cin>>w[i];
        cin>>str;
        sum[0]=w[str[0]-'a'];
        for(i=1;str[i];i++)
            sum[i]=sum[i-1]+w[str[i]-'a'];
        Manacher();
        int mx=0,len=strlen(str);
        for(i=0;i<len-1;i++)
        {
            int tmp=0,num=p[i+2]-1;
            if(num==i+1) tmp+=sum[i];
            num=p[i+len+2]-1;
            if(num==len-i-1) tmp+=sum[len-1]-sum[i];
            if(tmp>mx)
                mx=tmp;
        }
        cout<<mx<<endl;
    }
    return 0;
}

你可能感兴趣的:(算法)