79pts,拍出错的数据都巨大,完全调不动。。。
#include <bits/stdc++.h>
using namespace std;
struct LinkCutTree {
struct Node {
int ch[2];
int fa;
int val;
int sum;
int rev_tag;
};
vector<Node> tree;
map<pair<int, int>, bool> edge;
void init(int n, vector<int> &a) {
tree.resize(n + 10);
for (int i = 1; i <= n; ++i) {
tree[i].val = tree[i].sum = a[i];
tree[i].ch[0] = tree[i].ch[1] = tree[i].fa = tree[i].rev_tag = 0;
}
}
void pushUp(int x) {
tree[x].sum = tree[tree[x].ch[0]].sum ^ tree[tree[x].ch[1]].sum ^ tree[x].val;
}
void pushDown(int x) {
if (tree[x].rev_tag) {
swap(tree[tree[x].ch[0]].ch[0], tree[tree[x].ch[0]].ch[1]);
tree[tree[x].ch[0]].rev_tag ^= 1;
swap(tree[tree[x].ch[1]].ch[0], tree[tree[x].ch[1]].ch[1]);
tree[tree[x].ch[1]].rev_tag ^= 1;
tree[x].rev_tag = 0;
}
}
int get(int x) { return tree[tree[x].fa].ch[1] == x; }
int isRoot(int x) { return tree[tree[x].fa].ch[0] != x && tree[tree[x].fa].ch[1] != x; }
void rotate(int x) {
int y = tree[x].fa, z = tree[y].fa, t = get(x);
if (!isRoot(y)) tree[z].ch[get(y)] = x;
tree[y].ch[t] = tree[x].ch[t ^ 1], tree[tree[x].ch[t ^ 1]].fa = y;
tree[x].ch[t ^ 1] = y, tree[y].fa = x;
tree[x].fa = z;
pushUp(y), pushUp(x);
}
void update(int x) {
if (!isRoot(x)) update(tree[x].fa);
pushDown(x);
}
void splay(int x) {
update(x);
for (int fa = tree[x].fa; !isRoot(x); rotate(x), fa = tree[x].fa) {
if (!isRoot(fa)) rotate(get(fa) == get(x) ? fa : x);
}
}
int access(int x) {
splay(x);
tree[x].ch[1] = 0, pushUp(x);
while (tree[x].fa) {
int fa = tree[x].fa;
splay(fa), tree[fa].ch[1] = x, pushUp(fa);
x = fa;
}
return x;
}
void makeRoot(int x) {
access(x), splay(x);
swap(tree[x].ch[0], tree[x].ch[1]);
tree[x].rev_tag ^= 1;
}
int findRoot(int x) {
x = access(x);
pushDown(x);
while (tree[x].ch[0]) x = tree[x].ch[0], pushDown(x);
splay(x);
return x;
}
void link(int x, int y) {
if (findRoot(x) == findRoot(y)) return;
makeRoot(x), tree[x].fa = y;
edge[make_pair(x, y)] = edge[make_pair(y, x)] = 1;
}
void cut(int x, int y) {
if (!edge[make_pair(x, y)]) return;
makeRoot(x), access(x), tree[y].fa = 0;
edge[make_pair(x, y)] = edge[make_pair(y, x)] = 0;
}
void updVal(int x, int y) {
makeRoot(x), tree[x].val = y, pushUp(x);
}
int split(int x, int y) {
makeRoot(x);
return access(y);
}
} LCT;
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
vector<int> a(n + 10);
for (int i = 1; i <= n; ++i) cin >> a[i];
LCT.init(n, a);
while (m--) {
int opt, x, y;
cin >> opt >> x >> y;
if (opt == 0) {
cout << LCT.tree[LCT.split(x, y)].sum << '\n';
}
else if (opt == 1) {
LCT.link(x, y);
}
else if (opt == 2) {
LCT.cut(x, y);
}
else {
LCT.updVal(x, y);
}
}
return 0;
}