Manecher算法

这个算法用来处理字符串的回文串
p[i]-1表示第i个为中心的最长回文串的长度
算法比较容易
void Manacher()
{
    int mx = 0, id = 0;
    for (int i = 1; i <= len; i++)
    {

        if (mx > i)
            p[i] = min(mx - i, p[2 * id - i]);
        else
            p[i] = 1;
        while (h[i - p[i]] == h[i + p[i]] && h[i - p[i]] <= h[i - p[i] + 2])
            p[i]++;
        if (p[i] + i > mx)
        {
            mx = p[i] + i;
            id = i;
        }
    } 
}

最长回文串的长度L= max{ p[i] - 1 }(i>=1&&i<=n)




hdu 4513

这题是对算法的变形 只要在while里面加一个条件就ok了 h[i-p[i]]<=h[i-p[i]+2]

/*
* this code is made by LinMeiChen
* Problem: hdu4513
* Manecher算法
* 稍微变形一下,只需while()中加个条件 h[i-p[i]]<h[i-p[i]+2](注意中间有间隔东西)
*/ 
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include<string>
#include<vector>
#include<queue>
#include<list>
using namespace std; typedef long long lld; typedef unsigned int ud;
#define INF_MAX 0x3f3f3f3f
#define eatline() char chch;while((chch=getchar())!='\n')continue;
#define MemsetMax(a) memset(a,0x3f,sizeof a)
#define MemsetZero(a) memset(a,0,sizeof a)
#define MemsetMin(a) memset(a,-1,sizeof a)
#define MemsetFalse(a) MemsetZero(a)
#define PQ priority_queue
#define Q queue
#define maxn 100005
int h[maxn*2]; int p[maxn*2]; int main() { int T, n;
    scanf("%d", &T); while (T--) {
        scanf("%d", &n); int len = 0;
        h[len++] = -1; for (int i = 1; i <=n; i++) {
            h[len++] = -1;
            scanf("%d", &h[len]);
            len++; }
        h[len] = -1;
        //Manacher:
 int mx = 0, id = 0; for (int i = 1; i <= len; i++) { if (mx > i)
                p[i] = min(mx - i, p[2 * id - i]); else
                p[i] = 1; while (h[i - p[i]] == h[i + p[i]] && h[i - p[i]] <= h[i - p[i] + 2])
                p[i]++; if (p[i] + i>mx) {
                mx = p[i] + i;
                id = i; } } int ans = 0; for (int i = 1; i <= len; i++)
            ans = max(ans, p[i] - 1);
        printf("%d\n", ans); } return 0; }

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