Hotaru's problem HDU - 5371 (Manacher+枚举)

本文介绍了一个算法问题,即如何从给定序列中找到最大的连续N序列,并提供了详细的代码实现及样例解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hotaru's problem

HDU - 5371

Hotaru Ichijou recently is addicated to math problems. Now she is playing with N-sequence.
Let's define N-sequence, which is composed with three parts and satisfied with the following condition:
1. the first part is the same as the thrid part,
2. the first part and the second part are symmetrical.
for example, the sequence 2,3,4,4,3,2,2,3,4 is a N-sequence, which the first part 2,3,4 is the same as the thrid part 2,3,4, the first part 2,3,4 and the second part 4,3,2 are symmetrical.

Give you n positive intergers, your task is to find the largest continuous sub-sequence, which is N-sequence.

Input
There are multiple test cases. The first line of input contains an integer T(T<=20), indicating the number of test cases.

For each test case:

the first line of input contains a positive integer N(1<=N<=100000), the length of a given sequence

the second line includes N non-negative integers ,each interger is no larger than 109
, descripting a sequence.
Output
Each case contains only one line. Each line should start with “Case #i: ”,with i implying the case number, followed by a integer, the largest length of N-sequence.

We guarantee that the sum of all answers is less than 800000.
Sample Input
1
10
2 3 4 4 3 2 2 3 4 4
Sample Output
Case #1: 9

刚开始一直搞不懂为什么会有大于,觉得应该是等于

例子

321123321123

#3#2#1#1#2#3#3#2#1#1#2#3#

                          i           j

这个情况a[i]/2 > x

j = i+x

a[j]/2 = x;

code

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define maxn 200017
    int N;
    int p[maxn];
    int a[maxn];
    int b[maxn];
    int n;
    void init()
    {
        int i;
        for(i = 0; i < n; i ++)
        {
            b[2 * i + 1] = -1;
            b[2 * i + 2] = a[i];
        }
        N = 2 * i + 1;
        b[0] = -2;
        b[N] = b[N + 1] = -1;
    }
    void manacher()
    {
        int id;
        int maxx = 0;
        int ans = 0;
        for(int i = 1; i <= N; i ++)
        {
            if(maxx > i)
                p[i] = min(maxx-i, p[2*id-i]);
            else
                p[i] = 1;
            while(b[i + p[i]] == b[i - p[i]])
                ++ p[i];
            if(i + p[i] > maxx)
            {
                maxx = i + p[i];
                id = i;
            }
        }
    }
    int main()
    {
        int t;
        int cas = 0;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i = 0; i < n; i++)
            {
                scanf("%d",&a[i]);
            }
            init();
            manacher();
            int ans = 1;
            for(int i = 3; i < N; i+=2)
            {
                for(int j = ans; j <= p[i]; j+=2)
                {
                    if(p[i+j-1] >= j)
                    {
                        ans = j;
                    }
                }
            }
            ans = ans/2*3;
            printf("Case #%d: %d\n",++cas,ans);
        }
        return 0;
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值