hdoj4513(Manacher简单应用)

题目链接:https://vjudge.net/problem/HDU-4513

题意:给定一个整型数组,求最大回文串,而且该回文串满足回文串中心的左边递增,右边递减。

思路:
  Manacher算法简单应用。

  先用manacher算法求出p数组(p[i]表示以i为回文串中心的回文串最长是多少),然后从1到n遍历一遍,用len表示到第i个字符的不下降序列最长是多少,min(len , p[i])就是以i为回文串中心的满足题意的回文串的最长长度。

AC code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn=1e5+5;
int T,n,ans,a[maxn<<1],p[maxn<<1];

void manacher(){
    int mid=0,r=0;
    for(int i=1;i<n;++i){
        if(r>=i) p[i]=min(p[(mid<<1)-i],r-i+1);
        while(a[i-p[i]]==a[i+p[i]]) ++p[i];
        if(i+p[i]>r) r=i+p[i]-1,mid=i;
    }
}

int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        ans=0;
        a[0]=-1,a[1]=1;
        for(int i=0;i<n;++i){
            scanf("%d",&a[2*i+2]);
            a[2*i+3]=1;
        }
        n=2*n+2;
        for(int i=0;i<n;++i) p[i]=0;
        manacher();
        int len=0,top=0;
        for(int i=1;i<n;++i){
            if(a[i]==1){
                ++len;
            }
            else if(a[i]>=top){
                ++len;
                top=a[i];
            }
            else{
                len=2;
                top=a[i];
            }
            ans=max(ans,min(len,p[i]));
        }
        printf("%d
",ans-1);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/FrankChen831X/p/12411942.html