HDU 5371 - Hotaru's problem(Manacher算法)

来源:互联网 发布:手机上做班服的软件 编辑:程序博客网 时间:2024/04/26 07:56

题目:

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

题意:

求出三段连续的序列,使得第一段是第二段的回文,第二段是第三段的回文,求出最长序列是多长。

思路:

manacher算法,处理回文串。

枚举 i,满足mp[i] >= j-i+1 && mp[j] >= j-i+1, 更新答案 ans = j-i。

AC.

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <set>#pragma comment(linker,"/STACK:1024000000,1024000000")using namespace std;const int maxn = 1e5+5;int s[maxn*2];int mp[maxn*2];void manacher(int m){    int mx = 0, id = 0;    for(int i = 0; i < m; ++i) {        mp[i] = mx > i? min(mp[2*id-i], mx-i): 1;        while(s[i+mp[i]] == s[i-mp[i]]) mp[i]++;        if(i + mp[i] > mx) {            mx = i + mp[i];            id = i;        }    }}//最长回文序列的长度只会出现在打标记的地方。int main(){    //freopen("in", "r", stdin);    int T, ca = 0;    scanf("%d", &T);    while(T--) {        int n;        scanf("%d", &n);        int len = 0;        s[len++] = -1;        s[len++] = -10;        for(int i = 1; i <= n; ++i) {            scanf("%d", &s[len++]);            s[len++] = -10;        }        s[len++] = -1;        manacher(len);        int ans = 0;        for(int i = 1; i < len; i+=2) {            printf("%d %d\n", s[i], mp[i]);            for(int j = i+mp[i]-1; j - i > ans; j-=2) {                if(mp[j] >= j-i+1 && ans < j-i) {                    ans = j-i;                    break;                }            }        }        printf("Case #%d: %d\n", ++ca, ans/2*3);    }    return 0;}


0 0