本蒟蒻在写的时候觉得cut函数这种东西不是简简单单嘛, 直接判断一下在不在同一个树里就行了
然后同机房神犇(bilibili官方)难得找我问一次题 , 我便告诉他应该是这里错了(详情请见上一条帖子)
但是显而易见 , 我应该错了 , 必须加上那些特判
但是为什么我没加一开始写的也对了呢qwq????
代码如下
#include<bits/stdc++.h>
using namespace std ;
#define maxn 1005000
#define int long long
#define kkk signed main
inline int read(){
int ans = 0 , f = 1 ; char ch = getchar() ;
while ( ch < '0' || ch > '9') { if( ch == '-' ) f = -1 ; ch = getchar() ; }
while ( ch >= '0' && ch <= '9' ) ans = ( ans << 3 ) + ( ans << 1 ) + ch - '0' , ch = getchar() ;
return ans * f ;
}
int n , m ;
int val[maxn] , sum[maxn] , ch[maxn][2] , fa[maxn] , rev[maxn];
inline void pushup(int o){
sum[o] = val[o] ;
if(ch[o][0]) sum[o] ^= sum[ch[o][0]] ;
if(ch[o][1]) sum[o] ^= sum[ch[o][1]] ;
return ;
}
int s[maxn] , zz ;
inline bool isroot(int x){
return !fa[x] || ((ch[fa[x]][0] != x) && ch[fa[x]][1] != x) ;
}
inline void pushdown(int 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 ;
}
inline void rotate(int o){
int f = fa[o] ;
int g = fa[f] ;
bool c = (ch[f][1] == o) ;
fa[o] = g ;
fa[ch[o][c ^ 1]] = f ;
if(!isroot(f)) ch[g][ (ch[g][1] == f) ] = o ;
fa[f] = o ;
ch[f][c] = ch[o][c ^ 1] ;
ch[o][c ^ 1] = f ;
pushup(f) ;
}
inline void splay(int x){
int zz = 1 , now = x ;
s[1] = now ;
while(!isroot(now)) s[++zz] = now = fa[now] ;
while(zz) pushdown(s[zz--]) ;
while(!isroot(x)){
int f = fa[x] ;
if(!isroot(f)){
if((ch[fa[f]][0] == f) ^ (ch[f][0] == x)) rotate(x) ;
else rotate(f);
}
rotate(x) ;
}
pushup(x) ;
}
inline void access(int x){
for(int last = 0 ; x ; last = x , x = fa[x]){
splay(x) , ch[x][1] = last , pushup(x) ;
}
}
inline int find_root(int x){
access(x) ; splay(x) ;
while(ch[x][0]) x = ch[x][0] ;
pushup(x) ;
return x;
}
inline void makeroot(int x){
access(x) ;
splay(x) ;
rev[x] ^= 1 ;
}
inline void split(int x , int y){
makeroot(y) ;
access(x) ;
splay(x) ;
}
inline void link(int x , int y){
makeroot(x) ;
fa[x] = y ;
}
inline void cut(int x, int y){
makeroot(x) ;
access(y) ;
splay(y) ;
ch[y][0] = fa[x] = 0 ;
}
int op , x , y;
kkk(){
n = read() , m = read() ;
for(int i = 1 ; i <= n ; i++)
val[i] = read() ;
while(m--){
op = read() ; x = read() , y = read() ;
if(op == 0){
split(x , y) ;
printf("%lld\n" ,sum[x]) ;
}
else if(op == 1){
if(find_root(x) != find_root(y))
link(x , y) ;
}
else if(op == 2){
if(find_root(x) == find_root(y))
cut(x , y) ;
}
else{
val[x] = y ;
splay(x) ;
}
}
}