板题,只放代码。
const int N = 3e5 + 5;
inline ll Read() {
ll x = 0, f = 1;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -f, c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x * f;
}
namespace Main {
struct LCT {
int ch[N][2], fa[N], siz[N], val[N], sum[N], rev[N];
int get(int p) { return ch[fa[p]][1] == p; }
bool notroot(int p) { return ch[fa[p]][0] == p || ch[fa[p]][1] == p; }
void pushup (int p) { sum[p] = sum[ch[p][0]] ^ sum[ch[p][1]] ^ val[p]; }
void pushrev (int p) { rev[p] ^= 1; }
void pushdown (int p) {
if (!rev[p]) return;
swap(ch[p][0], ch[p][1]);
if (ch[p][0]) pushrev(ch[p][0]);
if (ch[p][1]) pushrev(ch[p][1]);
rev[p] = 0;
}
void rotate (int x) {
int y = fa[x], z = fa[y];
int k = get(x), w = ch[x][k ^ 1];
if (notroot(y)) ch[z][get(y)] = x;
ch[x][k ^ 1] = y; ch[y][k] = w;
if (w) fa[w] = y; fa[y] = x; fa[x] = z;
pushup(y);
}
int st[N];
void splay (int x) {
int y = x, top = 0; st[++top] = y;
for (; notroot(y); y = fa[y]) st[++top] = fa[y];
for (; top; top--) pushdown(st[top]);
for (; notroot(x); rotate(x)) {
if (notroot(fa[x])) rotate(get(x) == get(fa[x])? fa[x]: x);
}
pushup(x);
}
void access (int x) {
for (int y = 0; x; y = x, x = fa[x]) {
splay (x); ch[x][1] = y;
pushup (x);
}
}
void makeroot (int p) { access(p); splay(p); pushrev(p); }
void split (int p, int q) { makeroot(p); access(q); splay(q); }
void link (int p, int q) { split(p, q); fa[p] = q; }
void cut (int p, int q) {
split(p, q);
if (fa[p] != q) return;
ch[q][0] = fa[p] = 0;
pushup(q);
}
int query (int p, int q) { split(p, q); return sum[q]; }
}t;
int n, q;
int main () {
n = Read(), q = Read();
for (int i = 1; i <= n; i++) t.val[i] = Read();
for (; q--; ) {
int op = Read(), u = Read(), v = Read();
if(op == 0) printf("%d\n", t.query(u, v));
if(op == 1) t.link(u, v);
if(op == 2) t.cut(u, v);
if(op == 3) t.splay(u), t.val[u]=v;
}
return 0;
}
}
int main () {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
Main::main();
return 0;
}
EOF