HDU_3068
因为做中欧区域赛的题目时,题解有提到Manacher's ALGORITHM,于是就学了一下并找了两个题练练手,一个是HDU_3068还有一个是URAL_1297。推荐一篇讲这个算法讲的感觉挺清楚的博客:http://www.felix021.com/blog/read.php?2040。
View Code // HDU_3068
#include<stdio.h> #include<string.h> #include<algorithm> #define MAXD 220010 int N, p[MAXD]; char str[MAXD], b[MAXD]; void init() { int i; for(i = 0; str[i]; i ++) b[2 * i + 1] = '#', b[2 * i + 2] = str[i]; N = 2 * i + 1; b[0] = '$', b[N] = b[N + 1] = '#'; } void solve() { int i, id, max = 0, ans = 0; for(i = 1; i <= N; i ++) { p[i] = i < max ? std::min(max - i, p[2 * id - i]) : 1; while(b[i + p[i]] == b[i - p[i]]) ++ p[i]; if(i + p[i] > max) max = i + p[i], id = i; ans = std::max(ans, p[i] - 1); } printf("%d\n", ans); } int main() { while(scanf("%s", str) == 1) { init(); solve(); } return 0; }
View Code // URAL_1297
#include<stdio.h> #include<string.h> #include<algorithm> #define MAXD 220010 int N, p[MAXD]; char str[MAXD], b[MAXD]; void init() { int i; for(i = 0; str[i]; i ++) b[2 * i + 1] = '#', b[2 * i + 2] = str[i]; N = 2 * i + 1; b[0] = '$', b[N] = b[N + 1] = '#'; } void solve() { int i, j, k, id, max = 0, ans = 0; for(i = 1; i <= N; i ++) { p[i] = i < max ? std::min(max - i, p[2 * id - i]) : 1; while(b[i + p[i]] == b[i - p[i]]) ++ p[i]; if(i + p[i] > max) max = i + p[i], id = i; if(p[i] - 1 > ans) ans = p[i] - 1, k = (i - 1) / 2; } if(ans & 1) i = k - ans / 2, j = k + ans / 2; else i = k - ans / 2, j = k + ans / 2 - 1; for(; i <= j; i ++) printf("%c", str[i]); printf("\n"); } int main() { while(scanf("%s", str) == 1) { init(); solve(); } return 0; }