模板题咯,WC前练下手。
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 300005;
int n, m, w[maxn], fa[maxn], son[maxn][2], sum[maxn];
bool rev[maxn];
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
inline bool isroot(int x) {
return son[fa[x]][0] != x && son[fa[x]][1] != x;
}
inline void pushup(int x) {
sum[x] = w[x] ^ sum[son[x][0]] ^ sum[son[x][1]];
}
inline void pushdown(int x) {
if(rev[x]) {
rev[son[x][0]] ^= 1; rev[son[x][1]] ^= 1;
swap(son[x][0], son[x][1]);
rev[x] = 0;
}
}
int st[maxn];
inline void maintain(int x) {
int top = 0; st[++top] = x;
for(; !isroot(x); x = fa[x]) st[++top] = fa[x];
while(top) pushdown(st[top--]);
}
inline void rotate(int x) {
int y = fa[x], z = fa[y], type = son[y][1] == x;
fa[son[y][type] = son[x][!type]] = y;
fa[x] = z;
if(!isroot(y)) son[z][son[z][1] == y] = x;
fa[son[x][!type] = y] = x;
pushup(y); pushup(x);
}
inline void splay(int x) {
maintain(x);
while(!isroot(x)) {
int y = fa[x], z = fa[y];
if(isroot(y)) rotate(x);
else if(son[z][0] == y ^ son[y][0] == x) rotate(x), rotate(x);
else rotate(y), rotate(x);
}
}
inline void access(int x) {
for(int y = 0; x; x = fa[y = x]) {
splay(x);
son[x][1] = y;
pushup(x);
}
}
inline void makeroot(int x) {
access(x); splay(x); rev[x] ^= 1;
}
inline int findroot(int x) {
for(; !isroot(x); x = fa[x]);
return x;
}
inline void link(int x, int y) {
if(findroot(x) == findroot(y)) return;
makeroot(x); fa[x] = y;
}
inline void cut(int x, int y) {
makeroot(x); access(y); splay(y);
if(son[y][0] == x) son[y][0] = fa[x] = 0;
}
inline void change(int x, int c) {
makeroot(x); w[x] = c; pushup(x);
}
inline int query(int x, int y) {
makeroot(x); access(y); splay(y);
return sum[y];
}
int main() {
n = iread(); m = iread();
for(int i = 1; i <= n; i++) sum[i] = w[i] = iread();
while(m--) {
int opt = iread(), x = iread(), y = iread();
if(opt == 1) link(x, y);
else if(opt == 2) cut(x, y);
else if(opt == 3) change(x, y);
else if(x == y) printf("%d\n", w[x]);
else printf("%d\n", query(x, y));
}
return 0;
}