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

题目:

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值