用dfs序构建线段树,然后用lca求出两点间路径的xor和。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 100005 #define maxm 200005 #define eps 1e-7 #define mod 998244353 #define INF 0x3f3f3f3f #define PI (acos(-1.0)) #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R #define pii pair<int, int> #pragma comment(linker, "/STACK:16777216") typedef long long LL; typedef unsigned long long ULL; //typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} // head struct Edge { int v; Edge *next; }*H[maxn], *edges, E[maxm]; int anc[maxn][20]; int dep[maxn]; int in[maxn]; int out[maxn]; int a[maxn]; int sum[maxn << 4]; int lazy[maxn << 4]; const int M = 20; int dfs_clock, n, m; void addedges(int u, int v) { edges->v = v; edges->next = H[u]; H[u] = edges++; } void dfs(int u, int fa) { dfs_clock++; in[u] = dfs_clock; anc[u][0] = fa; for(Edge *e = H[u]; e; e = e->next) if(e->v != fa) { int v = e->v; dep[v] = dep[u] + 1; dfs(v, u); } out[u] = dfs_clock; } int to(int u, int d) { for(int i = M - 1; i >= 0; i--) if(dep[anc[u][i]] >= d) u = anc[u][i]; return u; } int lca(int u, int v) { if(dep[u] < dep[v]) swap(u, v); u = to(u, dep[v]); for(int i = M - 1; i >= 0; i--) if(anc[u][i] != anc[v][i]) u = anc[u][i], v = anc[v][i]; return u == v ? u : anc[u][0]; } void init() { dfs_clock = 0; dfs(1, 1); for(int i = 1; i < M; i++) for(int j = 1; j <= n; j++) anc[j][i] = anc[anc[j][i-1]][i-1]; } void pushup(int o) { sum[o] = sum[ls] ^ sum[rs]; } void pushdown(int o) { if(lazy[o]) { sum[ls] ^= lazy[o]; sum[rs] ^= lazy[o]; lazy[ls] ^= lazy[o]; lazy[rs] ^= lazy[o]; lazy[o] = 0; } } void build(int o, int L, int R) { lazy[o] = sum[o] = 0; if(L == R) return; int mid = (L + R) >> 1; build(lson); build(rson); pushup(o); } void update(int o, int L, int R, int ql, int qr, int v) { if(ql <= L && qr >= R) { lazy[o] ^= v; sum[o] ^= v; return; } pushdown(o); int mid = (L + R) >> 1; if(ql <= mid) update(lson, ql, qr, v); if(qr > mid) update(rson, ql, qr, v); pushup(o); } int query(int o, int L, int R, int q) { if(L == R) return sum[o]; pushdown(o); int ans = 0, mid = (L + R) >> 1; if(q <= mid) ans = query(lson, q); else ans = query(rson, q); pushup(o); return ans; } void work() { int u, v; scanf("%d%d", &n, &m); edges = E; memset(H, 0, sizeof H); for(int i = 1; i < n; i++) { scanf("%d%d", &u, &v); addedges(u, v); addedges(v, u); } for(int i = 1; i <= n; i++) scanf("%d", &a[i]), a[i]++; init(); build(1, 1, n); for(int i = 1; i <= n; i++) update(1, 1, n, in[i], out[i], a[i]); while(m--) { int kk; scanf("%d%d%d", &kk, &u, &v); if(kk) { int c = lca(u, v); int ans = query(1, 1, n, in[u]) ^ query(1, 1, n, in[v]) ^ a[c]; if(ans) printf("%d\n", ans-1); else printf("-1\n"); } else { ++v; update(1, 1, n, in[u], out[u], a[u] ^ v); a[u] = v; } } } int main() { int _; scanf("%d", &_); while(_--) work(); return 0; }