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