LCT的简单题。好久不写都手生了,还把rotate写错了一点点,导致找了半天错。
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
int _d_;
#define readInt(_s_) {\
_s_ = 0;\
while (!isdigit(_d_ = getchar()));\
while ((_s_ = _s_ * 10 + _d_ - 48), isdigit(_d_ = getchar()));\
}
const int maxn = 300009;
int n, m;
int ls[maxn], rs[maxn], pt[maxn], rv[maxn], vl[maxn], vs[maxn];
inline void update(const int& p) {
vs[p] = vs[ls[p]] ^ vl[p] ^ vs[rs[p]];
}
inline void fix(int p) {
if (rv[p]) {
swap(ls[p], rs[p]);
if (ls[p])
rv[ls[p]] ^= 1;
if (rs[p])
rv[rs[p]] ^= 1;
rv[p] = 0;
}
}
inline void lRot(int q) {
int p = pt[q], a = pt[p];
if (a) {
if (p == ls[a])
ls[a] = q;
else if (p == rs[a])
rs[a] = q;
}
if (rs[q])
pt[rs[q]] = p;
ls[p] = rs[q];
rs[q] = p;
pt[q] = a;
pt[p] = q;
update(p);
update(q);
}
inline void rRot(int q) {
int p = pt[q], a = pt[p];
if (a) {
if (p == ls[a])
ls[a] = q;
else if (p == rs[a])
rs[a] = q;
}
if (ls[q])
pt[ls[q]] = p;
rs[p] = ls[q];
ls[q] = p;
pt[q] = a;
pt[p] = q;
update(p);
update(q);
}
inline bool isRoot(int p) {
return !pt[p] || (p != ls[pt[p]] && p != rs[pt[p]]);
}
void splay(int q) {
static int stc[maxn];
int tst = 1, r = q;
stc[tst] = q;
while (!isRoot(q)) {
stc[++ tst] = pt[q];
q = pt[q];
}
while (tst)
fix(stc[tst --]);
q = r;
while (!isRoot(q)) {
int p = pt[q], a = pt[p];
if (isRoot(p)) {
if (q == ls[p])
lRot(q);
else
rRot(q);
}
else {
if (p == ls[a]) {
if (q == ls[p])
lRot(p), lRot(q);
else
rRot(q), lRot(q);
}
else {
if (q == ls[p])
lRot(q), rRot(q);
else
rRot(p), rRot(q);
}
}
}
}
int expose(int q) {
int p = 0;
for (; q; q = pt[q]) {
splay(q);
fix(q);
rs[q] = p;
update(q);
p = q;
}
fix(p);
while (ls[p]) {
p = ls[p];
fix(p);
}
return p;
}
void makeRoot(int p) {
expose(p);
splay(p);
rv[p] ^= 1;
}
void link(int u, int v) {
if (expose(u) == expose(v))
return;
makeRoot(u);
pt[u] = v;
}
void cut(int u, int v) {
makeRoot(u);
expose(v);
splay(v);
fix(v);
if (ls[v] != u)
return;
pt[u] = 0;
ls[v] = 0;
update(v);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
readInt(n);
readInt(m);
vl[0] = 0;
vs[0] = 0;
for (int i = 1; i <= n; ++ i) {
readInt(vl[i]);
vs[i] = vl[i];
ls[i] = 0;
rs[i] = 0;
pt[i] = 0;
rv[i] = 0;
}
while (m --) {
int opt, x, y;
readInt(opt);
readInt(x);
readInt(y);
if (opt == 0) {
makeRoot(x);
expose(y);
splay(y);
printf("%d\n", vs[y]);
}
else if (opt == 1) {
link(x, y);
}
else if (opt == 2) {
cut(x, y);
}
else if (opt == 3) {
splay(x);
vl[x] = y;
update(x);
}
}
}