hdu4513最长递增回文串

来源:互联网 发布:淘宝兼职画师 编辑:程序博客网 时间:2024/05/24 06:34

http://acm.hdu.edu.cn/showproblem.php?pid=4513

判断回文串的基础上使他的单侧递增

#include <iostream>#include <cstring>#include <cstdio>#include <cmath>using namespace std;const int maxn=1000005;int s[maxn],t[maxn<<1];int Len[maxn<<1];int init(int *st,int n){    int i;    t[0]=0;    for(i=1;i<=2*n;i+=2)    {        t[i]=300;        t[i+1]=st[i/2];    }    t[2*n+1]=300;    t[2*n+2]=400;    t[2*n+3]=0;    return 2*n+1;}//Manacher算法计算过程int manacher(int *st,int len){     int p=0,ans=0,po=0,k;//p即为当前计算回文串最右边字符的最大值     for(int i=1;i<=len;i++)     {         if(p>i)         Len[i]=min(p-i,Len[2*po-i]);//在Len[j]和p-i中取个小         else         Len[i]=1;//如果i>=p,要从头开始匹配         k=st[i];         while(st[i-Len[i]]==st[i+Len[i]]&&((st[i-Len[i]]==300)||st[i-Len[i]]<=k))//判断一下是否是递增的         {             if(st[i-Len[i]]!=300)             k=st[i-Len[i]];             Len[i]++;         }         if(Len[i]+i>p)//若新计算的回文串右端点位置大于p,要更新po和mx的值         {             p=Len[i]+i;             po=i;         }         ans=max(ans,Len[i]);     }     return ans-1;//返回Len[i]中的最大值-1即为原串的最长回文子串额长度  }int main(){    int T,n;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=0;i<n;i++)        scanf("%d",&s[i]);        int len=init(s,n);        int ans=manacher(t,len);        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击