[ SCOI 2016 ] 幸运数字

题目

Luogu
LOJ
Acwing

思路

1.png
2.png
3.png

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
const int N = 20010;
int n, m, B[N][61], P[N][61];
int h[N], ptr[N << 1], val[N << 1], idx;
int base[N], f[N][21], dep[N], w[N];
void add(int a, int b) { val[idx] = b, ptr[idx] = h[a], h[a] = idx++; }
void insert(int u, int B[], int P[]) {
	int x = w[u];
	for (int i = 60; i >= 0; i--) {
		if (!(x >> i & 1)) continue;
		if (!B[i]) { B[i] = x, P[i] = u; break; } // 不存在线性基
		if (dep[u] > dep[P[i]]) swap(P[i], u), swap(x, B[i]); // 比较一下深度
		x ^= B[i];
	}
}
void DFS(int u, int fa) {
	f[u][0] = fa, dep[u] = dep[fa] + 1;
	for (int i = 1; i <= 20; i++) // LCA 预处理父亲
		f[u][i] = f[f[u][i - 1]][i - 1]; 
	for (int i = 0; i <= 60; i++) // 复制父亲信息
		P[u][i] = P[fa][i], B[u][i] = B[fa][i];
	insert(u, B[u], P[u]);        // 用自己更新一下
	for (int i = h[u]; i != -1; i = ptr[i])
		if (val[i] != fa) DFS(val[i], u);
}
int LCA(int a, int b) { // 倍增LCA
	if (dep[a] < dep[b]) swap(a, b);
	for (int i = 20; i >= 0; i--)
		if (dep[f[a][i]] >= dep[b]) a = f[a][i];
	if (a == b) return a;
	for (int i = 20; i >= 0; i--)
		if (f[a][i] != f[b][i]) 
			a = f[a][i], b = f[b][i];
	return f[a][0];
}
int query(int a, int b) {
	int t = LCA(a, b);
	for (int i = 60; i >= 0; i--) // 首先把 a 到 LCA 的线性基全复制过来
		(dep[P[a][i]] >= dep[t]) ? base[i] = B[a][i] : base[i] = 0;
	for (int i = 60; i >= 0; i--) { 
		if (dep[P[b][i]] < dep[t]) continue; 
		int x = B[b][i]; // 暴力插入 b 到 LCA 的线性基
		for (int j = 60; j >= 0; j--)
			if (!(x >> j & 1)) continue;
			else if (!base[j]) { base[j] = x; break; }
			else x ^= base[j];
	}
	int res = 0; // 最大值
	for (int i = 60; i >= 0; i--)
		res = max(res, base[i] ^ res);
	return res;
}
signed main() {
	cin >> n >> m;
	memset(h, -1, sizeof h);
	for (int i = 1; i <= n; i++) cin >> w[i];
	for (int i = 1, a, b; i < n; i++)
		cin >> a >> b, add(a, b), add(b, a);
	DFS(1, 0);
	for (int a, b; m-- && cin >> a >> b; ) 
		cout << query(a, b) << endl;
	return 0;
}
posted @ 2021-04-16 15:40  Protein_lzl  阅读(42)  评论(0编辑  收藏  举报