51nod 1089 最长回文子串 V2(Manacher算法)

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
 收藏
 关注
回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。
输入一个字符串Str,输出Str里最长回文子串的长度。
 
Input
输入Str(Str的长度 <= 100000)
Output
输出最长回文子串的长度L。
Input示例
daabaac
Output示例
5


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <iomanip>
#include <math.h>
#include <map>
using namespace std;
#define FIN     freopen("input.txt","r",stdin);
#define FOUT    freopen("output.txt","w",stdout);
#define INF     0x3f3f3f3f
#define INFLL   0x3f3f3f3f3f3f3f
#define lson    l,m,rt<<1
#define rson    m+1,r,rt<<1|1
typedef long long LL;
typedef pair<int, int> PII;
using namespace std;

const int MAX = 200000 + 10;
char s[MAX * 2];//记得要开两倍
int p[MAX * 2];
int manacher(char *s) {
    int len = strlen(s), id = 0, ans = 0;
    for(int i = len; i >= 0; i--) {
        s[i + i + 2] = s[i];
        s[i + i + 1] = '#';
    }
    s[0] = '*';//防越界,很重要!!
    for(int i = 2; i < 2 * len + 1; ++i) {
        if(p[id] + id > i) p[i] = min(p[2 * id - i], p[id] + id - i);
        else p[i] = 1;
        while(s[i - p[i]] == s[i + p[i]]) p[i]++;
        if(id + p[id] < i + p[i]) id = i;
        ans = max(ans, p[i] - 1);
    }
    return ans;
}
int main() {
    //FIN
    char s[MAX];
    while(~scanf("%s", s)) {
        cout << manacher(s) << endl;
    }

    return 0;
}

  

原文地址:https://www.cnblogs.com/Hyouka/p/7447674.html