USACO Section 1.3 Calf Flac
manacher求最长子串。
/* PROG : calfflac LANG : C++ */ # include <cstdio> # include <cctype> # define N 20000 + 5 int n; char s[N]; int Min(int x, int y) { return x < y ? x : y; } int manacher(char *s, int len, int &st) { int n = len*2+1; char t[2 * N]; /* insert '#' in string s to form a 2*len+1 string t 在 s 中插入 len+1 个 '#' 使 s 中的奇偶回文字符串统一起来 */ for (int i = 0; i < len; ++i) { t[2*i] = '#'; t[2*i+1] = s[i]; } t[n-1] = '#'; int ret = 0; int p[2 * N]; int mx = 0, id; for (int i = 1; i < n; ++i) { p[i] = mx>i ? Min(p[2*id-i], mx-i):1; while (t[i-p[i]] == t[i+p[i]]) ++p[i]; if (i+p[i] > mx) mx = i+p[i], id = i; /* find the longest sub-palindrome, set ret and st(start position of LSP in s) */ if (p[i]-1 > ret) { ret = p[i] - 1; st = (i-p[i]+1)/2; } } return ret; } void solve(void) { int st; int r[N]; char ss[N]; int k = 0; for (int i = 0; i < n; ++i) { if (isalpha(s[i])) { r[k] = i; ss[k++] = tolower(s[i]); } } int len = manacher(ss, k, st); s[r[st+len-1]+1] = 0; printf("%d\n%s\n", len, s+r[st]); } int main() { freopen("calfflac.in", "r", stdin); freopen("calfflac.out", "w", stdout); n = 0; while ((s[n++]=getchar()) != EOF) ; solve(); fclose(stdin); fclose(stdout); return 0; }
manacher的资料;