码迷,mamicode.com
首页 > 编程语言 > 详细

manacher算法专题

时间:2016-05-07 16:25:13      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

一、模板

 

算法解析:http://www.felix021.com/blog/read.php?2040

 

 

 1 *主要用来解决一个字符串中最长回文串的长度,在O(n)时间内,线性复杂度下,求出以每个字符串为中心的最长回文,奇数回文跟偶数回文一起考虑了
 2 S  $ # 1 # 2 # 2 # 1 # 2 # 3 # 2 # 1 #
 3 P   1 2 1 2 5 2 1 4 1 2 1 6 1 2 1 2 1
 4 
 5 最后所求的值就是max(P[i]-1)
 6 
 7 //输入,并处理得到字符串s,s[0]=$
 8 void getp()
 9 {
10     int p[1000], mx = 0, id = 0;
11     memset(p, 0, sizeof(p));
12     for (i = 1; s[i] != \0; i++) 
13     {
14         p[i] = mx>i ? min(p[2*id-i], mx-i) : 1;
15         while (s[i + p[i]] == s[i - p[i]]) p[i]++;
16         if (i + p[i] > mx) 
17         {
18             mx = i + p[i];
19             id = i;
20         }
21     }
22 }

 

 

 

二、题目

1、【HDU 4513】吉哥系列故事――完美队形II

题意:输入n(1 <= n <= 100000)个人的身高hi(50 <= hi <= 250),从这些人中连续挑出k个人,这k个人【身高是左右对称的,如果是k是奇数,那么中间那个人的身高任意】&&【从左到中间那个人,身高需保证不下降,如果用H表示新队形的高度,则H[1] <= H[2] <= H[3] .... <= H[mid]】,求k的最大值。

解题思路:一般的manacher添加的是’#’,但是本题左半边的身高不递减,所以添加的应该是(h[i]+h[i+1])/2,注意细节。处理后的第奇数个身高是添加上去的,第偶数个身高是一开始输入的,当i-p[i]是奇数时,无论hh[i-p[i]]hh[i+p[i]]是否相等,p[i]都应该+1

比如:h[] = 80 60 70 60 90 50 ==> hh[] = -1 65 80 70 60 65 70 65 60 75 90 70 50 65【有颜色的是原串】,以70为中心时,p[6]=4而不是3

 

技术分享
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <string>
 6 using namespace std;
 7 const int N=2*1e5+10;
 8 int h[N], hh[N];
 9 int t, n;
10 int p[N], lenhh;
11 void getp()
12 {
13     int mx = 0, id = 0;
14     memset(p, 0, sizeof(p));
15     for (int i = 1; i<lenhh; i++) 
16     {
17         p[i] = mx>i ? min(p[2*id-i], mx-i) : 1;
18         while(hh[i + p[i]] == hh[i - p[i]] && hh[i-p[i]]<=hh[i-p[i]+1]) p[i]++;
19         if((i-p[i])%2) p[i]++;
20         if (i + p[i] > mx) 
21         {
22             mx = i + p[i];
23             id = i;
24         }
25     }
26 }
27 int main(){
28     scanf("%d", &t);
29     while(t--){
30         scanf("%d", &n);
31         for(int i=1; i<=n; i++){
32             scanf("%d", &h[i]);
33         }
34         h[0]=h[n], h[n+1]=h[1];
35         lenhh=2;
36         hh[1]=(h[0]+h[1])/2, hh[0]=-1;
37         for(int i=1; i<=n; i++){
38             hh[lenhh++]=h[i];
39             hh[lenhh++]=(h[i]+h[i+1])/2;
40         }
41 //        for(int i=0; i<lenhh; i++) cout<<hh[i]<<" ";
42 //        cout<<endl;
43         getp();
44         int maxn=0;
45 //        for(int i=0; i<lenhh; i++) cout<<p[i]<<" ";
46 //        cout<<endl;
47         for(int i=1; i<lenhh; i++) maxn = max(maxn, p[i]-1);
48         printf("%d\n", maxn);
49     }
50     return 0;
51 }
View Code

 

manacher算法专题

标签:

原文地址:http://www.cnblogs.com/yscc/p/5468444.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!