hdu 3068 最长回文 -Manacher
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
回文就是正反读都是一样的字符串,如aba, abba等
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa
abab
Sample Output
4 3
最长回文子串裸题,没什么好说的。扩展KMP似乎可以做,只不过不会,于是用的线性的Manacher
Code(到处都是修改)
1 /** 2 * hdu 3 * Problem#2068 4 * Accepted 5 * Time:280ms 6 * Memory:2632k 7 */ 8 #include<iostream> 9 #include<sstream> 10 #include<cstdio> 11 #include<cmath> 12 #include<cstdlib> 13 #include<cstring> 14 #include<cctype> 15 #include<queue> 16 #include<set> 17 #include<map> 18 #include<stack> 19 #include<vector> 20 #include<algorithm> 21 #ifdef WIN32 22 #define AUTO "%I64d" 23 #else 24 #define AUTO "%lld" 25 #endif 26 using namespace std; 27 typedef bool boolean; 28 #define smin(a, b) (a) = min((a), (b)) 29 #define smax(a, b) (a) = max((a), (b)) 30 inline boolean readLine(char* str) { 31 int index = 0; 32 char x; 33 while((x = getchar()) != '\n' && ~x) str[index++] = x; 34 str[index] = 0; 35 if(x == -1) { 36 ungetc(x, stdin); 37 return index != 0; 38 } 39 return true; 40 } 41 42 int len; 43 char S[110005]; 44 45 inline boolean init() { 46 // if(!readLine(S)) return false; 47 gets(S); 48 if(S[0] == 0) return false; 49 // if(scanf("%s", S) == -1) return false; 50 len = strlen(S); 51 return true; 52 } 53 54 int pi; 55 //char *newstr; 56 char newstr[220005]; 57 inline void change() { 58 pi = 1; 59 // newstr = new char[(const int)(2 * len + 3)]; 60 newstr[0] = '$'; 61 for(int i = 0; i < len; i++) { 62 newstr[pi++] = '#'; 63 newstr[pi++] = S[i]; 64 } 65 newstr[pi++] = '#'; 66 newstr[pi + 1] = 0; 67 } 68 69 //int* p; 70 int p[220005]; 71 inline void extends(int initer, int pos) { 72 p[pos] = initer; 73 int l = pos - initer, r = pos + initer; 74 while(newstr[l] == newstr[r]) l--, r++, p[pos]++; 75 } 76 77 inline int manacher() { 78 // p = new int[(const int)(pi + 1)]; 79 int R = 0, pos = 0; 80 int res = 1; 81 for(int i = 1; i <= pi; i++) { 82 /* if(i >= R) p[i] = 1; 83 else p[i] = min(R - i + 1, p[pos - (i - pos)]); 84 extends(p[i], i);*/ 85 if(i >= R) { 86 extends(1, i); 87 } else { 88 int j = pos - (i - pos); 89 if(i + p[j] < R) { 90 p[i] = p[j]; 91 } else { 92 extends(R - i + 1, i); 93 } 94 } 95 if(i + p[i] - 1 > R){ 96 R = i + p[i] - 1; 97 pos = i; 98 } 99 smax(res, p[i] - 1); 100 } 101 return res; 102 } 103 104 inline void solve() { 105 change(); 106 int len = manacher(); 107 printf("%d\n", len); 108 // delete[] p; 109 // delete[] newstr; 110 } 111 112 int main() { 113 // freopen("a.in", "r", stdin); 114 while(init()) { 115 solve(); 116 // readLine(S); 117 gets(S); 118 S[0] = 0; 119 } 120 return 0; 121 }