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 ", a); } else { if (!clor[x]) printf("%d ", b); else printf("%d ", c); } } } return 0; }