[LCA] NamomoCamp Daily 3

Posted 晁棠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LCA] NamomoCamp Daily 3相关的知识,希望对你有一定的参考价值。

NamomoCamp Daily 3

代码源oj网址http://oj.daimayuan.top/course/10/problem/451

题解:

主要是要了解异或的一个性质, a   x o r   b   x o r   b = a a \\ xor\\ b \\ xor\\ b = a a xor b xor b=a,那么在一棵树上,对于两个点 x , y x,y x,y的简单路径唯一,只需要求 x , y x,y x,y分别到根的异或和,异或一遍之再将 x , y x,y x,y的最近公共祖先再异或一遍回来就行。

注意

LCA计算层数的时候用bfs好一点。

代码:

// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm> 
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

const int N = 2e5 + 5;

int n, T, m;
int fa[N][20];
int pi, p[N], nxt[N * 2], to[N * 2];
int a[N], depth[N];
int s[N];

inline void add_in(int u, int v) 
	pi++; nxt[pi] = p[u]; p[u] = pi; to[pi] = v;


void bfs()

	mst(depth, inf);
	queue<int> q;
	q.push(1);
	depth[0] = 0; depth[1] = 1; s[1] = a[1];
	while (q.size()) 
		int u = q.front(); q.pop();
		for (int k = p[u], v = to[k]; k; k = nxt[k], v = to[k]) 
			if (depth[v] > depth[u] + 1) 
				depth[v] = depth[u] + 1;
				s[v] = a[v] ^ s[u];
				q.push(v);
				fa[v][0] = u;
				ffor(i, 1, 19)
					fa[v][i] = fa[fa[v][i - 1]][i - 1];
			
		
	


void ready()

	IOS;
	cin >> n >> m;
	ffor(i, 1, n) cin >> a[i];
	ffor(i, 1, n - 1) 
		int u, v;
		cin >> u >> v;
		add_in(u, v);
		add_in(v, u);
	
	bfs();


int LCA(int x, int y)

	if (depth[x] < depth[y]) swap(x, y);
	for (int i = 19; i >= 0; i--) 
		int xi = fa[x][i];
		if (depth[xi] >= depth[y]) x = xi;
	
	if (x == y) return x;
	for (int i = 19; i >= 0; i--) 
		if (fa[x][i] != fa[y][i]) 
			x = fa[x][i];
			y = fa[y][i];
		
	
	return fa[x][0];


void work()

	int x, y;
	cin >> x >> y;
	int anc = LCA(x, y), ans = s[x] ^ s[y] ^ a[anc];
	cout << ans << '\\n';


signed main()

	ready();
	while(m--)
	  work();
	return 0;






以上是关于[LCA] NamomoCamp Daily 3的主要内容,如果未能解决你的问题,请参考以下文章

[思维] NamomoCamp Daily 5

[思维] NamomoCamp Daily 7

[思维] NamomoCamp Daily 7

[前缀和] NamomoCamp Daily 4

[动态规划] NamomoCamp Daily 8

[动态规划] NamomoCamp Daily 8