关于cut函数的问题
查看原帖
关于cut函数的问题
246800
wocaicai楼主2020/6/17 22:17

本蒟蒻在写的时候觉得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) ; 
		}
	}
}

2020/6/17 22:17
加载中...