HDU 5371 Manacher Hotaru's problem

求出一个连续子序列,这个子序列由三部分ABC构成,其中AB是回文串,A和C相同,也就是BC也是回文串。

求这样一个最长的子序列。

Manacher算法是在所有两个相邻数字之间插入一个特殊的数字,比如-1,

Manacher算法跑完之后,就计算出每个数字为中心的回文子序列的最大长度

由题意可以知道,AB和BC必然是长度为偶数的回文串。所以我们枚举回文串的中心就枚举相邻两个数字之间的缝隙,也就是那些-1

把AB中间的间隙叫做左中心i,BC之间的间隙叫做右中心j,那么如果两个中心的范围能够互相覆盖,那么就找到一个符合条件的连续子序列。

做法就是枚举左中心i,在左中心的范围内枚举右中心j,然后维护一个最大值即可。

在枚举j的时候不要直接从[i+1, i + p[i] - 1]枚举,会超时的。

比如说我们维护的最大值是ans,那么直接从 i + ans 开始枚举,因为之前的区间即使找到合法子序列也并不能更新这个最大值。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 const int maxn = 100000 + 10;
 8
 9 int n, tot;
10 int a[maxn], b[maxn * 2];
11
12 int p[maxn * 2];
13
14 void Manacher()
15 {
16     int id, mx = 0;
17     p[0] = 0;
18     for(int i = 1; i < tot; i++)
19     {
20         if(mx > i) p[i] = min(p[id * 2 - i], mx - i);
21         else p[i] = 1;
22         while(b[i + p[i]] == b[i - p[i]]) p[i]++;
23         if(i + p[i] > mx) { mx = i + p[i]; id = i; }
24     }
25 }
26
27 int main()
28 {
29     int T; scanf("%d", &T);
30     for(int kase = 1; kase <= T; kase++)
31     {
32         scanf("%d", &n);
33         for(int i = 0; i < n; i++) scanf("%d", a + i);
34
35         b[0] = -2, b[1] = -1;
36         tot = 2;
37         for(int i = 0; i < n; i++)
38         {
39             b[tot++] = a[i];
40             b[tot++] = -1;
41         }
42
43         Manacher();
44
45         int ans = 1;
46         for(int i = 3; i < tot; i += 2)
47         {
48             for(int j = ans; j <= p[i]; j += 2)
49                 if(p[i + j - 1] >= j) ans = j;
50         }
51
52         ans = ans / 2 * 3;
53         printf("Case #%d: %d\n", kase, ans);
54     }
55
56     return 0;
57 }

代码君

HDU 5371 Manacher Hotaru's problem

时间: 2024-08-16 16:59:23

HDU 5371 Manacher Hotaru's problem的相关文章

【HDOJ 5371】 Hotaru&#39;s problem

[HDOJ 5371] Hotaru's problem Manacher算法+穷举/set Manacher算法一好文:http://blog.csdn.net/yzl_rex/article/details/7908259 套一个Manacher算出回文半径数组p之后 有两种方法 穷举法: 枚举-1的点(根据题意只必为偶数回文) 找在该点回文半径内与其相隔最远 并且回文半径等于他俩距离(即两点为中心的回文串相同) 的点 记录找到时的距离 不断枚举找最大值即为最大回文串长 串长/2*3即为答案

hdu 5371 manacher+枚举

容易联想到利用manacher算法获得len数组,然后枚举第二段的长度判断能否和第三段对应上,能的话就更新答案. 另外枚举长度的时候,小于等于当前答案的长度就没有必要枚举了,不然可能会超时. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 100007; 7 int num[N]; 8 int tmp[N <

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&#39;s problem(manacher+二分/枚举)

HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分相同,第一部分与第二部分对称. 现在给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法,求出以第i个点为中心的回文串长度,记录到数组p中 要满足题目所要求的内容,需要使得两个相邻的回文串,共享中间的一部分,也就是说,左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也是一样. 因为我们已经记录下来以

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&amp;#39;s problem(manacher+二分/枚举)

pid=5371">HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分同样,第一部分与第二部分对称. 如今给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法.求出以第i个点为中心的回文串长度.记录到数组p中 要满足题目所要求的内容.须要使得两个相邻的回文串,共享中间的一部分,也就是说.左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也

HDU 5371 Hotaru&#39;s problem (Manacher,回文串)

题意:给一个序列,找出1个连续子序列,将其平分成前,中,后等长的3段子序列,要求[前]和[中]是回文,[中]和[后]是回文.求3段最长为多少?由于平分的关系,所以答案应该是3的倍数. 思路:先Manacher求最长子串,利用期间所记录的P 数组,穷举一下所有可能的前两串,再用O(1)时间判断第3串是否符合要求. 具体做法: (1)P[i]记录的是以i为中心,从i-P[i]+1到i+P[i]-1这段都是回文.由于前两段之和必为偶数,所以必须选取str[i]为'#'的. (2)扫一遍每个'#',以其

HDU 5371 Hotaru&#39;s problem manacher+(线段树or set)

题意,给定一个100000 的串,求他一个子串,使得将子串分成三部分有后,第一部分=第三部分,第一部分与第二部分对称(回文) 首先我们需要处理出以i为轴的回文串的两端,这个事情可以用Manacher算法完成,复杂度O(n) http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ 这个博客写的很好懂.不会的童鞋可以去学习一下这个算法,非常精妙. 好的现在我们已经会了这个算法,并获得了每个点为轴的串的右端点p[i] 很简单地可以处理出左端

hdu 5371 Hotaru&#39;s problem【manacher】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5371 题意: 给出一个长度为n的串,要求找出一条最长连续子串.这个子串要满足:1:可以平均分成三段,2:第一段和第三段相等,3:第一段和第二段回文.求最大子串的长度. 代码: #include<stdio.h> #include<iostream> #include<math.h> #include<stdlib.h> #include<ctype.h&

HDU 5371 Hotaru&#39;s problem(manacher + 枚举啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5371 Problem Description 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 foll

hdu 5371 Hotaru&#39;s problem(manacher+尺取法)

题意: 给定一个有n个数字的序列,找出一个连续的子序列满足这样的条件: 1. 平均分成三段 2. 第一段与第三段一样 3. 第二段是第一段的倒序.求这样的子序列的最大长度. 数据范围:n~100000 解析: 我看网络上面很多的题解都是用O(n2/32)的做法水数据过去的,这种做法是先用mancher算法预处理出每个每个回文串最远所能抵达的位置,然后枚举每个位置i,再枚举其回文串的长度,然后枚举当前位置i到回文串所能抵达的最远距离,判断途径的位置j是,否有回文串能够到当前位置i.但是这种做法的复