牛客练习赛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;
}
寻找真正的热爱

浙公网安备 33010602011771号