Manacher(马拉车)

Manacher(马拉车)

 

 1 #include<iostream>  
 2 #include<string.h>
 3 #include<algorithm>  
 4 #include <cstdio>
 5 using namespace std;
 6  
 7 const int N  = 1e7 + 1e6 + 100;
 8 char s[N];
 9 char s_new[N * 2];
10 int p[N * 2];
11  
12 int Init()
13 {
14     int len = strlen(s);
15     s_new[0] = '$';
16     s_new[1] = '#';
17     int j = 2;
18  
19     for (int i = 0; i < len; i++){
20         s_new[j++] = s[i];
21         s_new[j++] = '#';
22     }
23  
24     s_new[j] = '\0';  //别忘了哦  
25  
26     return j;  //返回s_new的长度  
27 }
28  
29 int Manacher()
30 {
31     int len = Init();  //取得新字符串长度并完成向s_new的转换  
32     int maxlen = -1;   //最长回文长度  
33  
34     int id;
35     int mx = 0;
36  
37     for (int i = 1; i < len; i++){
38         if (i < mx) p[i] = min(p[2 * id - i], mx - i);  //需搞清楚上面那张图含义, mx和2*id-i的含义
39         else p[i] = 1;
40          //不需边界判断,因为左有'$',右有'\0' 
41         while (s_new[i - p[i]] == s_new[i + p[i]]) p[i]++;
42  
43         //我们每走一步i,都要和mx比较,我们希望mx尽可能的远,这样才能更有机会执行if (i < mx)这句代码,从而提高效率 
44         if (mx < i + p[i])  {
45             id = i;
46             mx = i + p[i];
47         }
48  
49        
50     }
51     for(int i = 0; i < len; ++i) { printf("%d ", i); } printf("\n");
52     for(int i = 0; i < len; ++i) { printf("%d ", p[i]); } printf("\n");
53     for(int i = 0; i < len; ++i) { printf("%c ", s_new[i]); } printf("\n");
54 
55     for(int i = 0; i < len; ++i){
56         if(s_new[i] == '#') maxlen = max(maxlen, (p[i] - 1) / 2 * 2);
57         else if(s_new[i] != '$') maxlen = max(maxlen, p[i] - 1);
58     }
59     return maxlen;
60 }
61 int main()
62 {
63     scanf("%s", s);
64     printf("%d\n", Manacher());
65  
66     return 0;
67 }

 

posted @ 2020-05-21 20:13  SummerMingQAQ  阅读(199)  评论(0编辑  收藏  举报