hdu 3068 最长回文 -Manacher

  给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 
回文就是正反读都是一样的字符串,如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 }

 


posted @ 2017-01-29 20:50  阿波罗2003  阅读(153)  评论(0编辑  收藏  举报