本人不会lct,所以没有用它提交,尽量别喷谢谢
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
struct Node {
int val; // 节点的值
int xor_sum; // 子树异或和
int rev; // 翻转标记
Node *ch[2]; // 左右孩子
Node *fa; // 父亲节点
Node(int v) : val(v), xor_sum(v), rev(0), ch{nullptr, nullptr}, fa(nullptr) {}
};
class LinkCutTree {
private:
// 判断节点是否是某个子树的根
bool is_root(Node *x) {
return x->fa == nullptr || (x->fa->ch[0] != x && x->fa->ch[1] != x);
}
// 下传翻转标记
void push_down(Node *x) {
if (x->rev) {
swap(x->ch[0], x->ch[1]);
if (x->ch[0]) x->ch[0]->rev ^= 1;
if (x->ch[1]) x->ch[1]->rev ^= 1;
x->rev = 0;
}
}
// 更新子树异或和
void push_up(Node *x) {
x->xor_sum = x->val;
if (x->ch[0]) x->xor_sum ^= x->ch[0]->xor_sum;
if (x->ch[1]) x->xor_sum ^= x->ch[1]->xor_sum;
}
// 旋转操作
void rotate(Node *x) {
Node *y = x->fa;
Node *z = y->fa;
int k = (y->ch[1] == x);
if (!is_root(y)) z->ch[z->ch[1] == y] = x;
x->fa = z;
y->ch[k] = x->ch[k ^ 1];
if (x->ch[k ^ 1]) x->ch[k ^ 1]->fa = y;
x->ch[k ^ 1] = y;
y->fa = x;
push_up(y);
push_up(x);
}
// Splay 操作
void splay(Node *x) {
vector<Node*> stk;
for (Node *y = x; !is_root(y); y = y->fa) stk.push_back(y->fa);
while (!stk.empty()) {
push_down(stk.back());
stk.pop_back();
}
push_down(x);
while (!is_root(x)) {
Node *y = x->fa;
if (!is_root(y)) rotate((y->ch[1] == x) == (y->fa->ch[1] == y) ? y : x);
rotate(x);
}
}
// 将 x 到根的路径变为实链
void access(Node *x) {
for (Node *y = nullptr; x; y = x, x = x->fa) {
splay(x);
x->ch[1] = y;
push_up(x);
}
}
// 将 x 设为根
void make_root(Node *x) {
access(x);
splay(x);
x->rev ^= 1;
}
// 查找 x 的根
Node* find_root(Node *x) {
access(x);
splay(x);
while (x->ch[0]) {
push_down(x);
x = x->ch[0];
}
splay(x);
return x;
}
// 连接 x 和 y
void link(Node *x, Node *y) {
make_root(x);
if (find_root(y) != x) x->fa = y;
}
// 断开 x 和 y 的边
void cut(Node *x, Node *y) {
make_root(x);
if (find_root(y) == x && y->fa == x && !y->ch[0]) {
y->fa = x->ch[1] = nullptr;
push_up(x);
}
}
// 查询 x 到 y 的路径异或和
int query_xor(Node *x, Node *y) {
make_root(x);
access(y);
splay(y);
return y->xor_sum;
}
// 修改 x 的权值
void modify(Node *x, int val) {
splay(x);
x->val = val;
push_up(x);
}
unordered_map<int, Node*> nodes; // 节点映射
public:
// 初始化节点
void init_node(int x, int val) {
nodes[x] = new Node(val);
}
// 连接 x 和 y
void link(int x, int y) {
link(nodes[x], nodes[y]);
}
// 删除 x 和 y 的边
void cut(int x, int y) {
cut(nodes[x], nodes[y]);
}
// 查询 x 到 y 的路径异或和
int query_xor(int x, int y) {
return query_xor(nodes[x], nodes[y]);
}
// 修改 x 的权值
void modify(int x, int val) {
modify(nodes[x], val);
}
};
int main() {
LinkCutTree lct;
int n, m;
cin >> n >> m;
// 初始化节点
for (int i = 1; i <= n; ++i) {
int val;
cin >> val;
lct.init_node(i, val);
}
// 处理操作
while (m--) {
int op, x, y;
cin >> op >> x >> y;
if (op == 0) {
cout << lct.query_xor(x, y) << endl;
} else if (op == 1) {
lct.link(x, y);
} else if (op == 2) {
lct.cut(x, y);
} else if (op == 3) {
lct.modify(x, y);
}
}
return 0;
}