社区讨论

倍增LCA0分求调

P10113[GESP202312 八级] 大量的工作沟通参与者 1已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@m4glcozk
此快照首次捕获于
2024/12/09 13:27
去年
此快照最后确认于
2025/11/04 13:05
4 个月前
查看原帖
CPP
#include<iostream>
#include<cstring>
using namespace std;

const unsigned int N = 5 * 1e5+2;

int n, cnt = 0;
struct Edge
{
	int t, next;
}e[2 * N];
int head[N], depth[N], fa[N][9], lg[N], fa_max[N];
bool p_tf[N];

inline void add_e(int u, int v) { e[++cnt] = { v , head[u] }; head[u] = cnt; }

void Get_depth(int d, int sum, int maxn)
{
	maxn = max(d, maxn);
	fa_max[d] = maxn;
	p_tf[d] = 0;
	depth[d] = sum;
	for (int i = head[d]; i; i = e[i].next) if (p_tf[e[i].t]) Get_depth(e[i].t, sum + 1, maxn);
}

inline void Get_log()
{
    lg[0] = 0;
	for (int i = 1; i <= n; i++)
		lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
}

void Dfs_fa(int d, int fath)
{
	fa[d][0] = fath;
	for (int i = 1; i <= lg[depth[d]]; i++) fa[d][i] = fa[fa[d][i - 1]][i - 1];
	for (int i = head[d]; i; i = e[i].next) if (e[i].t != fath) Dfs_fa(e[i].t, d);
}

inline int Get_LCA(int a, int b)
{
	if (depth[a] < depth[b]) swap(a, b);
	while (depth[a] > depth[b])
		a = fa[a][lg[depth[a] - depth[b] - 1]];
	if (a == b) return b;
	for (int i = lg[depth[a]] - 1; i >= 0; i--)
		if (fa[a][i] != fa[b][i])
			a = fa[a][i], b = fa[b][i];
	return fa[a][0];
}

int main()
{
	memset(head, 0, sizeof(head));
	memset(p_tf, true, sizeof(p_tf));
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n;
	int in;
	for (int i = 1; i < n; i++)
	{
		cin >> in;
		add_e(in, i);
		add_e(i, in);
	}
	Get_depth(0, 1, 0);
	Get_log();
	Dfs_fa(0, 0);
	int Q;
	cin >> Q;
	int num, a, b;
	while (Q--)
	{
		cin >> num
			>> a;
		num--;
		while (num--)
		{
			cin >> b;
			a = Get_LCA(a, b);
		}
		cout << fa_max[a]
			 << '\n';
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...