【BZOJ4044】【Cerc2014】Virus synthesis

【题目链接】

【思路要点】

  • 补档博客,无题解。

【代码】

#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;
}

猜你喜欢

转载自blog.csdn.net/qq_39972971/article/details/80081722