1 2 3 4

牛客练习赛58 XOR TREE

https://ac.nowcoder.com/acm/contest/4090/F

8说了,就是个树链剖分

当xy之间的距离是奇数,就考虑重新建个1010101010--这样取值的树,

当xy之间距离是偶数,直接就完整的取异或就行了,没啥难得,树链剖分板子题8

 

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 771;
int read()
{
	int x = 0;
	char c = getchar();
	while (c<'0' || c>'9') c = getchar();
	while (c >= '0'&&c <= '9') x = (x << 1) + (x << 3) + c - '0', c = getchar();
	return x;
}
int head[maxn];
struct Node {
	int to;
	int nxt;
}G[maxn * 2];
int z;
void add(int be, int en) {
	G[++z].to = en;
	G[z].nxt = head[be];
	head[be] = z;
}
int tree[maxn * 5];
int arr[maxn];
int xo[maxn * 5];
int n;
int m;

int clor[maxn];
int dep[maxn], id[maxn], son[maxn], fa[maxn], siz[maxn];
int top[maxn];


int dfs(int x, int f, int d, int cl) {
	clor[x] = cl;
	dep[x] = d;
	fa[x] = f;
	siz[x] = 1;
	int s = 0;
	for (int i = head[x]; i; i = G[i].nxt) {
		int p = G[i].to;
		if (p == f) continue;
		dfs(p, x, d + 1, cl ^ 1);
		siz[x] += siz[p];
		if (s < siz[p]) {
			s = siz[p];
			son[x] = p;
		}
	}
	return 0;
}
int cnt = 0;
int dfs2(int x, int t) {
	id[x] = ++cnt;
	top[x] = t;
	if (son[x]) dfs2(son[x], t);
	for (int i = head[x]; i; i = G[i].nxt) {
		int p = G[i].to;
		if (p == fa[x] || p == son[x]) continue;
		dfs2(p, p);
	}
	return 0;
}
//以上是dfs和建立图的部分

#define L 2*node
#define R 2*node+1

int update(int node, int be, int en, int i, int val, int *tr) {
	int mid = be + en >> 1;
	if (be == en) {
		tr[node] = val;
		return 0;
	}
	if (i <= mid) update(L, be, mid, i, val, tr);
	if (i > mid) update(R, mid + 1, en, i, val, tr);
	tr[node] = (tr[L] ^ tr[R]);
	return 0;
}
int qurry(int node, int be, int en, int LL, int RR, int *tr) {
	int mid = be + en >> 1;
	int val1 = 0, val2 = 0;
	if (en < LL || be > RR) return 0;
	if (LL <= be && en <= RR) {
		return tr[node];
	}
	val1 = qurry(L, be, mid, LL, RR, tr);
	val2 = qurry(R, mid + 1, en, LL, RR, tr);
	return (val1 ^ val2);
}




int ask(int x, int y, int &ans, int &ans2, int &len) {
	ans = 0;
	ans2 = 0;
	len = 0;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);

		int cns = qurry(1, 1, n, id[top[x]], id[x], tree);
		len += id[x] - id[top[x]] + 1;
		int cns2 = qurry(1, 1, n, id[top[x]], id[x], xo);
		ans ^= cns;
		ans2 ^= cns2;

		x = fa[top[x]];
	}

	if (dep[x] > dep[y]) swap(x, y);
	//x现在在y上面,id更小
	int cns = qurry(1, 1, n, id[x], id[y], tree);//注意顺序
	ans ^= cns;
	len += id[y] - id[x] + 1;
	cns = qurry(1, 1, n, id[x], id[y], xo);
	ans2 ^= cns;


	return 0;
}


int a, b;
int main() {

	n = read();
	m = read();
	for (int i = 1; i <= n; i++) {
		arr[i] = read();
	}
	int be, en;
	for (int i = 1; i < n; i++) {
		be = read();
		en = read();
		add(be, en);
		add(en, be);
	}
	dfs(1, -1, 0, 1);
	dfs2(1, 1);

	for (int i = 1; i <= n; i++) {
		update(1, 1, n, id[i], arr[i], tree);
		if (clor[i]) update(1, 1, n, id[i], arr[i], xo);
	}
	while (m--) {
		int op, x, y;
		op = read(); x = read(); y = read();
		if (op == 1) {
			update(1, 1, n, id[x], y, tree);
			if (clor[x]) update(1, 1, n, id[x], y, xo);
		}
		else {//求和啦
			int len = 0;
			ask(x, y, a, b, len);
			int c = a ^ b;
			if (len % 2 == 0) {
				printf("%d\n", a);
			}
			else {
				if (!clor[x]) printf("%d\n", b);
				else printf("%d\n", c);
			}
		}
	}
	return 0;
}

  

posted @ 2020-03-26 19:46  Lesning  阅读(134)  评论(0编辑  收藏  举报