求助,#8 WA,结果好像偏大
查看原帖
求助,#8 WA,结果好像偏大
109442
pV_equals_nRT楼主2023/12/14 23:10
#include <cstdio>
#include <algorithm>

const int N = 1000005;
int t, m, fa[N][25], deep[N], lg2[N], k = 4, ans = 2;

void find(int x, int f) {
	deep[x] = deep[f] + 1;
	fa[x][0] = f;
	for (int i = 1; i <= lg2[deep[x]]; i++) {
		fa[x][i] = fa[fa[x][i - 1]][i - 1];
	}
}

int lca(int x, int y) {
	if (deep[x] < deep[y]) {
		std::swap(x, y);
	}
	while (deep[x] != deep[y]) {
		x = fa[x][lg2[deep[x] - deep[y]]];
	}
	if (x == y) {
		return x;
	}
	for (int i = lg2[deep[x]]; i >= 0; i--) {
		if (fa[x][i] != fa[y][i]) {
			x = fa[x][i];
			y = fa[y][i];
		}
	}
	return fa[x][0];
}

int main() {
	int l1 = 2, l2 = 2, r1 = 3, r2 = 3;
	scanf("%d", &m);
	for (int i = 2; i <= m * 2 + 4; i++) {
		lg2[i] = lg2[i / 2] + 1;
	}
	find(2, 1), find(3, 1), find(4, 1);
	for (int i = 1, u; i <= m; i++) {
		scanf("%d", &u);
		find(++k, u);
		find(++k, u);
		if (u == l1 || u == l2) {
			printf("%d\n", ++ans);
			l1 = k - 1, l2 = k;
		} else if (u == r1 || u == r2) {
			printf("%d\n", ++ans);
			r1 = k - 1, r2 = k;
		} else {
			int c1 = lca(l1, u), c2 = lca(r1, u);
			if (deep[l1] - deep[c1] + deep[u] - deep[c1] + 1 > ans) {
				ans++;
				l1 = k - 1, l2 = k;
			} else if (deep[r1] - deep[c2] + deep[u] - deep[c2] + 1 > ans) {
				ans++;
				r1 = k - 1, r2 = k;
			}
			printf("%d\n", ans);
		}
	}
}

思路大概是,每次检测新加进来的点,如果加在直径两端就ans++,否则检测这个点是否生成新直径
但不知道哪里错了

2023/12/14 23:10
加载中...