#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/exception.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/list_update_policy.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/trie_policy.hpp>
// using namespace __gnu_pbds;
// tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>T;
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef long double ldb;
//#define umap unordered_map
#define umap __gnu_pbds::cc_hash_table
#define mkp make_pair
#define prque priority_queue
#define emp emplace
#define empb emplace_back
#define empf emplace_front
random_device rndv;
mt19937 rd(rndv());
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const double eps = 1e-8;
const vector<ll> millerrabin = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
inline void enter(){putchar('\n');}
inline void space(){putchar(' ');}
inline ll readll(){ll ret=0,k=1;char c;do{c=getchar();if(c=='-'){k=-1;}}while(('0'>c)|('9'<c));do{ret=(ret<<3)+(ret<<1)+c-48;c=getchar();}while(('0'<=c)&(c<='9'));return ret*k;}
inline void read(ll&x){x=readll();}
inline char readchar(){char ret;do{ret=getchar();}while(ret<=32);return ret;}
inline void read(char&x){x=readchar();}
inline string readstr(){string ret;char c;do{c=getchar();}while(c<=32);do{ret+=c;c=getchar();}while((c>32)&(c!=EOF));return ret;}
inline void read(string&x){x=readstr();}
inline void write(ll x){if(!x){putchar('0');return;}if(x<0){putchar('-');x*=-1;}char op[20]={};ll cur=0;while(x){op[++cur]=x%10+48;x/=10;}while(cur){putchar(op[cur--]);}}
inline ostream& operator<<(ostream& out, __int128 x){if(!x){out<<"0";return out;}if(x<0){out<<"-";x*=-1;}char op[40]={};ll cur=0;while(x){op[++cur]=x%10+48;x/=10;}while(cur){out<<op[cur--];}return out;}
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const ll MAXN = 3e5 + 5;
struct LCTNode {
ll l, r, p, xr, val, rev;
LCTNode() {
l = r = p = xr = val = rev = 0;
}
};
struct LCT {
LCTNode node[MAXN];
void lock() {
node[0] = LCTNode();
}
void pushup(ll x) {
lock();
node[x].xr = node[x].val ^ node[node[x].l].xr ^ node[node[x].r].xr;
}
void pushdown(ll x) {
lock();
if (node[x].rev) {
swap(node[x].l, node[x].r);
}
node[node[x].l].rev ^= node[x].rev;
node[node[x].r].rev ^= node[x].rev;
lock();
node[x].rev = 0;
}
bool isr(ll x) {
lock();
return x && node[node[x].p].l != x && node[node[x].p].r != x;
}
bool isl(ll x) {
return x && !isr(x) && node[node[x].p].l == x;
}
void upd(ll x) {
if (!isr(x)) {
upd(node[x].p);
}
pushdown(x);
}
void rtt(ll x) {
if (!x || isr(x)) {
return;
}
ll p = node[x].p, g = node[p].p;
pushdown(g), pushdown(p), pushdown(x);
if (!isr(p)) {
if (isl(p)) {
node[g].l = x;
} else {
node[g].r = x;
}
}
if (isl(x)) {
node[p].l = node[x].r;
node[node[x].r].p = p;
node[x].r = p;
} else {
node[p].r = node[x].l;
node[node[x].l].p = p;
node[x].l = p;
}
node[p].p = x;
node[x].p = g;
pushup(p), pushup(x), pushup(g);
}
void spl(ll x) {
if (!x) {
return;
}
upd(x);
while (!isr(x) && !isr(node[x].p)) {
ll p = node[x].p;
if (isl(p) == isl(x)) {
rtt(p);
} else {
rtt(x);
}
rtt(x);
}
rtt(x);
}
void acc(ll x) {
if (!x) {
return;
}
for (ll s = 0; x; s = x, x = node[x].p) {
spl(s), spl(x);
node[x].r = s, node[s].p = x;
lock();
pushup(x);
}
}
void mkr(ll x) {
acc(x), spl(x);
pushdown(x);
node[x].rev = 1;
pushdown(x);
}
void spt(ll x, ll y) {
mkr(x), acc(y), spl(y);
}
ll fnd(ll x) {
acc(x), spl(x);
pushdown(x);
while (node[x].l) {
x = node[x].l;
pushdown(x);
}
// =========================================
spl(x);
// =========================================
return x;
}
void link(ll x, ll y) {
if (fnd(x) == fnd(y)) {
return;
}
mkr(x), mkr(y);
node[y].p = x;
pushup(y), pushup(x);
}
void cut(ll x, ll y) {
if (fnd(x) != fnd(y)) {
return;
}
spt(x, y);
if (node[x].r) {
return;
}
node[x].p = node[y].l = 0;
pushup(x), pushup(y);
}
void setval(ll x, ll v) {
spt(x, x);
node[x].xr = node[x].val = v;
}
ll getval(ll x, ll y) {
spt(x, y);
return node[y].xr;
}
} lct;
ll n, q;
int main() {
read(n), read(q);
for (ll i = 1; i <= n; ++i) {
ll v;
read(v);
lct.setval(i, v);
}
while (q--) {
ll o, x, y;
read(o), read(x), read(y);
if (o == 0) {
write(lct.getval(x, y)), enter();
} else if (o == 1) {
lct.link(x, y);
} else if (o == 2) {
lct.cut(x, y);
} else {
lct.setval(x, y);
}
}
return 0;
}
为什么代码第 149 行那个 splay 删掉就过不去样例 2