RT,第九个点RE,是因为在判断连通前加了makeroot()的原因吗
#include <bits/stdc++.h>
using namespace std;
#define N 8000100
#define ll long long
inline ll read(){
ll x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){
if(c == '-')s = -1;
c = getchar();
}
while(isdigit(c)){
x = x * 10 + c - '0';
c = getchar();
}
return x * s;
}
ll fa[N], ch[N][2], rev[N], que[N], len, val[N];
ll sum[N], a[N];
ll is_lc(ll o){
return ch[fa[o]][1] == o;
}
bool is_root(ll o){
return !fa[o] || (ch[fa[o]][0] != o && ch[fa[o]][1] != o);
}
void pushup(ll o){
sum[o] = sum[ch[o][0]] ^ sum[ch[o][1]] ^ a[o];
return ;
}
void pushdown(ll o){
if(rev[o]){
swap(ch[o][0], ch[o][1]);
if(ch[o][0]) rev[ch[o][0]] ^= 1;
if(ch[o][1]) rev[ch[o][1]] ^= 1;
rev[o] = 0;
}
return ;
}
void rotate(ll x){
ll y = fa[x], z = fa[y], b = ch[y][0] == x ? ch[x][1] : ch[x][0];
if(z && !is_root(y)) (ch[z][0] == y ? ch[z][0] : ch[z][1]) = x;
fa[x] = z; fa[y] = x;
b ? fa[b] = y : 0;
if(ch[y][0] == x) ch[x][1] = y, ch[y][0] = b;
else ch[x][0] = y, ch[y][1] = b;
pushup(y);
pushup(x);
return ;
}
void splay(ll x){
ll i, y;
que[len = 1] = x;
for(y = x; !is_root(y); y = fa[y]) que[++len] = fa[y];
for(i = len; i >= 1; i--) pushdown(que[i]);
while(!is_root(x)){
if(!is_root(fa[x])){
if(is_lc(x) == is_lc(fa[x])) rotate(fa[x]);
else rotate(x);
}
rotate(x);
}
pushup(x);
return ;
}
void access(ll x){
for(ll y = 0; x; y = x, x = fa[x]){
splay(x);
ch[x][1] = y;
if(y) fa[y] = x;
pushup(x);
}
return ;
}
inline void make_root(ll x){
access(x);
splay(x);
rev[x] ^= 1;
return ;
}
ll find_root(ll x){
make_root(x);
access(x);
splay(x);
while(ch[x][0]) x = ch[x][0];
splay(x);
return x;
}
inline void link(ll x, ll y){
make_root(x);
fa[x] = y;
return ;
}
inline void split(ll x, ll y){
make_root(x);
access(y);
splay(y);
return ;
}
inline void cut(ll x, ll y){
split(x, y);
ch[y][0] = 0;
fa[x] = 0;
pushup(y);
return ;
}
inline ll query(ll x, ll y){
split(x, y);
return sum[y];
}
inline void change(ll x, ll w){
splay(x);
a[x] = w;
pushup(x);
return ;
}
inline bool is_link(ll x, ll y){
make_root(x); make_root(y);
return find_root(x) == find_root(y);
}
int main(){
freopen("测试.txt", "r", stdin);
freopen("out.txt", "w", stdout);
ll n = read(), q = read();
for(ll i = 1;i <= n; i++) a[i] = read();
while(q--){
ll flag = read();
ll x = read(), y = read();
switch(flag){
case 0:
printf("%lld\n", query(x, y));
break;
case 1:
if(!is_link(x, y)) link(x, y);
break;
case 2:
if(is_link(x, y)) cut(x, y);
break;
case 3:
change(x, y);
break;
}
}
return 0;
}