回文自动机
多串后缀自动机 / 广义后缀自动机
深度优先搜索 (dfs,大法师)
void Manacher() {
int n = 2, i, Max = 0, M = 0;
t[0] = 2, t[1] = 1;
for (i = 0; i < S; ++i) t[n++] = s[i], t[n++] = 1; t[n++] = 3;
for (i = 0; i < n; ++i){
f[i] = (i < Max ? std::min(f[M * 2 - i], Max - i) : 1);
for(; t[i + f[i]] == t[i - f[i]]; ++f[i]);
if (i + f[i] > Max) Max = i + f[i], M = i;
}
}
int get_fail(int x) {for (; ptr[~val[x]] != *ptr; x = fail[x]); return x;}
int extend(int x) {
int &q = d[p = get_fail(p)][x];
if (!q) fail[++cnt] = d[get_fail(fail[p])][x], val[q = cnt] = val[p] + 2;
return p = q;
}
val[1] = -1, p = 0, *fail = cnt = 1;
#define q d[p][x]
#define try_split(v) { \
if (val[p] + 1 == val[q]) v = q; \
else { \
int nq = ++cnt; \
val[nq] = val[p] + 1, memcpy(d[nq], d[q], 104); \
pa[nq] = pa[q], v = pa[q] = nq; \
for (int Q = q; p && q == Q; q = nq, p = pa[p]); \
} \
}
int extend(int x) {
if (p = np, q) try_split(np)
else {
for (val[np = ++cnt] = val[p] + 1; p && !q; q = np, p = pa[p]);
if (p) try_split(pa[np]) else pa[np] = 1;
}
return np;
}
#undef q
// implementation 1
void dfs(int x){
int i, y;
// do something
for(i = first[x]; i; i = next[i])
if((y = to[i]) != p[x]){