HDU 3068 longest retrieval Manacher algorithm,
The Manacher algorithm is an O (n) algorithm that solves the Palindrome problem. It can be said that it is a super algorithm. It kills all other Palindrome solutions, including complex Suffix Arrays.
Many explanations on the Internet, the best parsing article of course is Leetcode: http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html
Here we will summarize the key points:
1. New characters are inserted between the characters of the original string, for example, "#". It is convenient to unify all character centers. For example, the character centers of aa and aba are different. The character centers of aa are aa, the center of aba is B, and after inserting #, aa becomes # a #. The Center is a character #, while aba inserts # a # B # #, the center is still a character B.
2. Make full use of the previously calculated information to calculate the subsequent information. Here we mainly use the symmetry of palindrome, then we can use the information of the first half of the symmetric center to calculate the information of the second half. This is the key to optimizing the algorithm to O (n. Because the symmetric center is constantly shifted to the right, the solution in the symmetric center only needs to copy the information of the first half segment, and expand Palindrome is required if it is beyond the current symmetric range.
3. prevent overflow. add an additional special character, such '~ ', Which is different from the previous inserted characters. We also need to insert characters later, but why do many programs not insert characters? That is because the char of C ++ ends with '\ 0'. Therefore, it is acceptable not to insert the char. The following program inserts' \ 0' to the end.
4. You need to maintain the rightmost vertex information, center information, and P array. The meaning of the P array is the length of the longest palindrome substring centered on the I point. Here the length is + 1, which is convenient for calculation.
The key code is just a few lines, but the idea is very difficult.
#include <stdio.h>#include <string.h>const int MAX_2L = 220010;char txt[MAX_2L];int P[MAX_2L];int len;inline int min(int a, int b) { return a < b? a : b; }inline int max(int a, int b) { return a > b? a : b; }void preProcess(){len = strlen(txt);int i = len-1, j = (len<<1);txt[j+2] = '\0';txt[j+1] = '#';for ( ; i >= 0; i--){txt[j--] = txt[i];txt[j--] = '#';}txt[0] = '~';}int main(){while (gets(txt)){preProcess();len = len << 1 | 1;int maxLen = 0, right = 0, center = 0;for (int i = 1; i <= len; i++){P[i] = i<right ? min(P[(center<<1)-i], right-i) : 1;while (txt[i-P[i]] == txt[i+P[i]]) P[i]++;maxLen = max(maxLen, P[i]);if (right < i+P[i]) center = i, right = i+P[i];}printf("%d\n", maxLen-1);gets(txt); //get rid of empty line}return 0;}