hdu 3068 最长回文 【Manacher求最长回文子串,模板题】

来源:互联网 发布:入门拳击手套 知乎 编辑:程序博客网 时间:2024/06/11 23:43

欢迎关注__Xiong的博客: http://blog.csdn.net/acmore_xiong?viewmode=list

最长回文

                                                               Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
                                                                                                  Total Submission(s): 11760    Accepted Submission(s): 4308
                                                                                 链接:Click Me!
Problem Description
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
 
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
 
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
 
Sample Input
aaaaabab
 
Sample Output
43
 

分析:

求解最长回文串,以前我是用DP来做的,在这个题目里面,O(N^2)的复杂度肯定是会超时的,于是我今天第一回敲了个Manacher的模板,挺方便的,复杂度也降了一个数量级,复杂度只有O(N),Orz...

实现代码:

#include <map>#include <cmath>#include <queue>#include <vector>#include <cstdio>#include <string>#include <cstring>#include <sstream>#include <iostream>#include <algorithm>using namespace std;#define FIN             freopen("input.txt","r",stdin)#define FOUT            freopen("output.txt","w",stdout)#define CASE(T)         int T;for(scanf("%d",&T);T--;)const int maxn = 110000 + 5;char Ma[maxn << 1];int Mp[maxn << 1];void Manacher(char s[], int len){    int l = 0;    Ma[l++] = '$';    Ma[l++] = '#';    for(int i = 0; i < len; i++)    {        Ma[l++] = s[i];        Ma[l++] = '#';    }    Ma[l] = 0;    int mx = 0, id = 0;    for(int i = 0; i < l; i++)    {        Mp[i] = mx > i ? min(Mp[2 * id - i], mx - i) : 1;        while(Ma[i + Mp[i]] == Ma[i - Mp[i]]) Mp[i]++;        if(i + Mp[i] > mx)        {            mx = i + Mp[i];            id = i;        }    }}char s[maxn];int main(){#ifndef ONLINE_JUDGE    FIN;#endif // ONLINE_JUDGE    while(~scanf("%s", s))    {        int len = strlen(s);        Manacher(s, len);        int ans = 0;        for(int i = 0; i < 2 * len + 2; i++)        {            ans = max(ans, Mp[i] - 1);        }        printf("%d\n", ans);    }    return 0;}

2 2
原创粉丝点击