写码30min,调码3h的题。。
好在最后查出来了
171 else T.modify(1, 1, n, x, y, z);
改成了
171 else T.modify(1, 1, n, mark[x], y, z);
然后$40 ightarrow 100$
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define re register 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i) 7 #define repd(i, a, b) for (re int i = a; i >= b; --i) 8 #define For(i, a, b, s) for (re int i = a; i <= b; s) 9 #define maxx(a, b) a = max(a, b) 10 #define minn(a, b) a = min(a, b) 11 #define LL long long 12 #define INF (1 << 30) 13 14 #define Finline __inline__ __attribute__ ((always_inline)) 15 extern Finline char get_char(){ 16 static char buf[1000001], *p1 = buf, *p2 = buf; 17 return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1 ++; 18 } 19 20 template <typename T> 21 inline void read(T &w) { 22 w = 0; char c = get_char(); 23 while (!isdigit(c)) c = get_char(); 24 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ 48), c = get_char(); 25 } 26 27 const int maxn = 1e5 + 5; 28 29 int n, m, k; 30 31 struct Node { 32 unsigned LL v; 33 int opt; 34 } a[maxn], b[maxn]; 35 36 struct Edge { 37 int u, v, pre; 38 } e[maxn << 1]; 39 int ec, G[maxn]; 40 void init() { ec = 0; memset(G, -1, sizeof(G)); } 41 void add(int u, int v) { e[ec++] = (Edge){u, v, G[u]}; G[u] = ec-1; } 42 #define iter(i, u) for (register int i = G[u]; i != -1; i = e[i].pre) 43 44 int par[maxn], topf[maxn], son[maxn], link[maxn], mark[maxn], dep[maxn], cnt; 45 void dfs1(int u, int fa) { 46 par[u] = fa; son[u] = 1; link[u] = u; dep[u] = dep[fa]+1; 47 iter(i, u) 48 if (e[i].v != fa) { 49 dfs1(e[i].v, u); 50 if (son[e[i].v] >= son[link[u]]) link[u] = e[i].v; 51 son[u] += son[e[i].v]; 52 } 53 } 54 void dfs2(int u, int fa, int head) { 55 mark[u] = ++cnt; topf[u] = head; a[cnt] = b[u]; 56 if (link[u] != u) dfs2(link[u], u, head); 57 iter(i, u) 58 if (e[i].v != fa && e[i].v != link[u]) 59 dfs2(e[i].v, u, e[i].v); 60 } 61 // opt: 1->& 2->| 3->^ 62 inline unsigned LL calc(unsigned LL a, unsigned LL b, int opt) { 63 if (opt == 1) return a & b; 64 else if (opt == 2) return a | b; 65 else return a ^ b; 66 } 67 68 #define connect(v, a, b) (((v)&(b))|(~(v)&(a))) 69 70 struct Seg_T { 71 #define lson (o << 1) 72 #define rson (o << 1 | 1) 73 unsigned LL l0[maxn << 4], l1[maxn << 4], r0[maxn << 4], r1[maxn << 4]; 74 void pushup(int o) { 75 l0[o] = connect(l0[lson], l0[rson], l1[rson]); 76 l1[o] = connect(l1[lson], l0[rson], l1[rson]); 77 r0[o] = connect(r0[rson], r0[lson], r1[lson]); 78 r1[o] = connect(r1[rson], r0[lson], r1[lson]); 79 } 80 void build(int o, int l, int r) { 81 if (l == r) { 82 l0[o] = r0[o] = calc((unsigned LL)0, a[l].v, a[l].opt); 83 l1[o] = r1[o] = calc(~(unsigned LL)0, a[l].v, a[l].opt); 84 return; 85 } 86 int mid = (l + r) >> 1; 87 build(lson, l, mid), build(rson, mid+1, r); 88 pushup(o); 89 } 90 void modify(int o, int l, int r, int p, int opt, unsigned LL v) { 91 if (l == r) { 92 l0[o] = r0[o] = calc((unsigned LL)0, v, opt); 93 l1[o] = r1[o] = calc(~(unsigned LL)0, v, opt); 94 return; 95 } 96 int mid = (l + r) >> 1; 97 if (p <= mid) modify(lson, l, mid, p, opt, v); else modify(rson, mid+1, r, p, opt, v); 98 pushup(o); 99 } 100 void lquery(int o, int l, int r, int ql, int qr, unsigned LL &L0, unsigned LL &L1) { 101 if (ql <= l && r <= qr) { 102 L0 = connect(L0, l0[o], l1[o]); 103 L1 = connect(L1, l0[o], l1[o]); 104 return; 105 } 106 int mid = (l + r) >> 1; 107 if (ql <= mid) lquery(lson, l, mid, ql, qr, L0, L1); 108 if (mid < qr) lquery(rson, mid+1, r, ql, qr, L0, L1); 109 } 110 void rquery(int o, int l, int r, int ql, int qr, unsigned LL &R0, unsigned LL &R1) { 111 if (ql <= l && r <= qr) { 112 R0 = connect(R0, r0[o], r1[o]); 113 R1 = connect(R1, r0[o], r1[o]); 114 return; 115 } 116 int mid = (l + r) >> 1; 117 if (mid < qr) rquery(rson, mid+1, r, ql, qr, R0, R1); 118 if (ql <= mid) rquery(lson, l, mid, ql, qr, R0, R1); 119 } 120 } T; 121 122 #define swap(a, b) a ^= b ^= a ^= b 123 int s[maxn], size = 0; 124 125 unsigned LL query_link(int x, int y, unsigned LL z) { 126 unsigned LL l0 = 0, l1 = ~l0, r0 = 0, r1 = ~r0; 127 while (topf[x] != topf[y]) { 128 if (dep[topf[x]] > dep[topf[y]]) { 129 T.rquery(1, 1, n, mark[topf[x]], mark[x], l0, l1); 130 x = par[topf[x]]; 131 } else { 132 unsigned LL l = 0, r = ~l; 133 T.lquery(1, 1, n, mark[topf[y]], mark[y], l, r); 134 l = connect(l, r0, r1); 135 r = connect(r, r0, r1); 136 r0 = l, r1 = r; 137 y = par[topf[y]]; 138 } 139 } 140 if (dep[x] > dep[y]) T.rquery(1, 1, n, mark[y], mark[x], l0, l1); 141 else T.lquery(1, 1, n, mark[x], mark[y], l0, l1); 142 l0 = connect(l0, r0, r1); l1 = connect(l1, r0, r1); 143 int flag = 1; unsigned LL res = 0, bit; 144 repd(i, k-1, 0) { 145 bit = (unsigned LL)1 << i; 146 if (l0 & bit) res |= bit; 147 if (flag) { 148 if (z & bit) { 149 if (!(l0 & bit) && (l1 & bit)) res |= bit; 150 else flag = 0; 151 } 152 } else 153 if (!(l0 & bit) && (l1 & bit)) res |= bit; 154 } 155 return res; 156 } 157 158 int main() { 159 init(); 160 read(n), read(m), read(k); 161 rep(i, 1, n) read(b[i].opt), read(b[i].v); 162 rep(i, 1, n-1) { 163 int u, v; read(u), read(v); 164 add(u, v), add(v, u); 165 } 166 dfs1(1, 1), dfs2(1, 1, 1); 167 T.build(1, 1, n); 168 rep(i, 1, m) { 169 int Q, x, y; unsigned LL z; read(Q), read(x), read(y), read(z); 170 if (Q == 1) printf("%llu ", query_link(x, y, z)); 171 else T.modify(1, 1, n, mark[x], y, z); 172 } 173 return 0; 174 }