manacher算法入门HDU5731

来源:互联网 发布:中国证券软件下载 编辑:程序博客网 时间:2024/05/23 00:01

马拉车算法,线性求出回文串。。具体就不讲了,可以参考博博客链接客

说下这个题的想法,,,首先求出每个数字的回文串长度(包括-1的)。然后枚举每一个数,在他的回文串长度内,继续枚举右区间,看右区间有没有回文串长度和左区间一样长的。然后求个最大值就好了。。。就是说 在2 3 4 4 3 2 2 3 4 中找到了最长的回文串 2 3 4 4 3 2.然后枚举4 3 2看他们的回文串长度有没有回文串长度比前面小的。就相当于找了两个回文串,中间的部分既属于前半部分,又属于后半部分!

顺便带上manacher的模板

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<iostream>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<set>#include<map>#include<string>using namespace std;typedef long long ll;typedef pair<int,int>P;const int INF=0x3f3f3f3f;const ll INFF=0x3f3f3f3f3f3f3f3f;const double pi=acos(-1.0);const double eps=1e-9;int n;int a[200010];int b[200010];int len[200010];void manacher(){    int l=0;a[l++]=-2,a[l++]=-1;    for(int i=1;i<=n;i++){a[l++]=b[i];a[l++]=-1;}a[l]=-3;    int mx=0,pos=0;    for(int i=0;i<l;i++)    {        if(mx>i)len[i]=min(mx-i,len[2*pos-i]);        else len[i]=1;        while(a[i-len[i]]==a[i+len[i]])len[i]++;        if(len[i]+i>mx)        {            mx=len[i]+i;pos=i;        }    }    //for(int i=1;i<l;i++)    //    printf("len[%d]==%d\n",i,len[i]);}int main(){    int t,ca=1;scanf("%d",&t);    while(t--)    {        printf("Case #%d: ",ca++);scanf("%d",&n);        for(int i=1;i<=n;i++)scanf("%d",&b[i]);        manacher();        int ans=0;        for(int i=1;i<=n*2+1;i+=2)        {            for(int j=i+len[i]-1;j-i>ans;j-=2)            {                if(j-i+1<=len[j])                {                    ans=max(ans,j-i);                    break;                }            }        }        printf("%d\n",ans*3/2);    }    return 0;}


原创粉丝点击