【题目链接】
【思路要点】
- 补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 100005 template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } struct Palindromic_Tree { int child[MAXN][4], from[MAXN], far[MAXN]; int father[MAXN], depth[MAXN]; int dp[MAXN], s[MAXN]; int home[MAXN], now[MAXN], index[MAXN]; vector <int> a[MAXN]; int root, size, len, last; int new_node(int x) { size++; a[size].clear(); father[size] = 0; from[size] = 0; depth[size] = x; memset(child[size], 0, sizeof(child[size])); return size; } void Extend(int ch, int pos) { int p = last; while (p != root && s[pos] != s[pos - depth[p] - 1]) p = father[p]; if (s[pos] != s[pos - depth[p] - 1]) { last = root; return; } if (p == root) { if (!child[p][ch]) { int now = new_node(depth[p] + 2); father[now] = root; child[root][ch] = now; } } else if (!child[p][ch]) { int q = father[p], now = new_node(depth[p] + 2); while (q != root && s[pos] != s[pos - depth[q] - 1]) q = father[q]; if (s[pos] != s[pos - depth[q] - 1]) father[now] = root; else father[now] = child[q][ch]; child[p][ch] = now; } last = child[p][ch]; from[last] = p; } void init(char *x) { s[0] = -1; size = 0; len = strlen(x + 1); for (int i = 1; i <= len; i++) { if (x[i] == 'A') s[i] = 1; if (x[i] == 'C') s[i] = 2; if (x[i] == 'G') s[i] = 3; if (x[i] == 'T') s[i] = 0; } last = root = new_node(0); for (int i = 1; i <= len; i++) Extend(s[i], i); for (int i = 2; i <= size; i++) a[father[i]].push_back(i); } void work(int root, int dep) { now[dep] = depth[root]; index[dep] = root; home[dep] = home[dep - 1]; while (home[dep] < dep && now[home[dep] + 1] * 2 <= depth[root]) home[dep]++; far[root] = index[home[dep]]; for (unsigned i = 0; i < a[root].size(); i++) work(a[root][i], dep + 1); } void getans() { dp[0] = 1; work(root, 1); int ans = len; for (int i = 1; i <= size; i++) { dp[i] = dp[from[i]] + (depth[i] - depth[from[i]]) / 2; dp[i] = min(dp[i], dp[far[i]] + (depth[i] / 2 - depth[far[i]]) + 1); if (depth[i] == depth[far[i]] * 2) dp[i] = min(dp[far[i]] + 1, dp[i]); ans = min(ans, len - depth[i] + dp[i]); } printf("%d\n", ans); } } PT; char s[MAXN]; int main() { int T; read(T); while (T--) { scanf("\n%s", s + 1); PT.init(s); PT.getans(); } return 0; }