1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| #include <cstdio> #include <vector> #define pb push_back using namespace std; template <class Type> void read (Type &x) { char c; bool flag = false; while ((c = getchar()) < '0' || c > '9') c == '-' && (flag = true); x = c - '0'; while ((c = getchar()) >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - '0'; flag && (x = ~x + 1); } template <class Type, class ...rest> void read (Type &x, rest &...y) { read(x), read(y...); } template <class Type> void write (Type x) { x < 0 && (putchar('-'), x = ~x + 1); x > 9 && (write(x / 10), 0); putchar('0' + x % 10); } const int N = 1e5 + 10, M = 30; int n, q, w[N], d[N], p[N], sz[N]; int stmp, dfn[N], son[N], top[N]; vector <int> g[N]; int idx, rt[2][N]; struct Trie { int s[2], c; } tr[2 * N * (M + 1)]; void insert (int &x, int k, int t = M - 1) { tr[++idx] = tr[x]; x = idx; ++tr[x].c; if (!~t) return; insert(tr[x].s[k >> t & 1], k, t - 1); } int query (vector <int> &x, vector <int> &y, int k, int t = M - 1) { if (!~t) return 0; int c = k >> t & 1, s = 0; for (int i : x) s -= tr[tr[i].s[c ^ 1]].c; for (int i : y) s += tr[tr[i].s[c ^ 1]].c; if (s > 0) { for (int &i : x) i = tr[i].s[c ^ 1]; for (int &i : y) i = tr[i].s[c ^ 1]; return query(x, y, k, t - 1) | 1 << t; } else { for (int &i : x) i = tr[i].s[c]; for (int &i : y) i = tr[i].s[c]; return query(x, y, k, t - 1); } } void dfs1 (int u) { sz[u] = 1; for (int v : g[u]) if (v ^ p[u]) { p[v] = u; d[v] = d[u] + 1; dfs1(v); sz[u] += sz[v]; if (sz[v] > sz[son[u]]) son[u] = v; } } void dfs2 (int u, int t) { top[u] = t; dfn[u] = ++stmp; insert(rt[0][stmp] = rt[0][stmp - 1], w[u]); insert(rt[1][u] = rt[1][p[u]], w[u]); if (!son[u]) return; dfs2(son[u], t); for (int v : g[u]) if (v ^ p[u] && v ^ son[u]) dfs2(v, v); } int lca (int a, int b) { while (top[a] ^ top[b]) { if (d[top[a]] < d[top[b]]) swap(a, b); a = p[top[a]]; } if (d[a] > d[b]) swap(a, b); return a; } int main () { read(n, q); for (int i = 1; i <= n; ++i) read(w[i]); for (int i = 1, a, b; i < n; ++i) read(a, b), g[a].pb(b), g[b].pb(a); insert(rt[0][0], 0), insert(rt[1][0], 0); dfs1(1), dfs2(1, 1); for (int op; q; --q) { read(op); if (op == 1) { int t, k; read(t, k); vector <int> a {rt[0][dfn[t] - 1] }, b { rt[0][dfn[t] + sz[t] - 1] }; write(query(a, b, k)), puts(""); } else if (op == 2) { int x, y, k; read(x, y, k); int t = lca(x, y); vector <int> a { rt[1][t], rt[1][p[t]] }, b { rt[1][x], rt[1][y] }; write(query(a, b, k)), puts(""); } } return 0; }
|