玄关FHQ-treap WA10~12
查看原帖
玄关FHQ-treap WA10~12
506356
zsfzyj楼主2025/1/21 10:51
#include<bits/stdc++.h>
using namespace std ;
const int N = 1e5+10 ;
int n , op , x , tot , root ;
struct FHQ_Treap{
	int ls , rs , rnd , val , siz ;
}tr[N];
#define ls(u) tr[u].ls
#define rs(u) tr[u].rs
#define rnd(u) tr[u].rnd
#define val(u) tr[u].val
#define siz(u) tr[u].siz
template<class T>
void read(T &x){
	x = 0 ; int f = 1 ;
	char c = getchar() ;
	while(!isdigit(c)) f = (c == '-' ? -f : f) , c = getchar() ;
	while(isdigit(c)) x = (x<<3)+(x<<1)+(c^48) , c = getchar() ;
	x *= f ;
}
void put_s(string s){
	int len = s.size() ;
	for(int i = 0 ; i < len ; i++) putchar(s[i]) ;
}
template<class T>
void write(T x , string s){
	if(x < 0) putchar('-') , x = -x ;
	if(x >= 10) write(x/10 , "") ;
	putchar('0'+x%10) ;
	if(s.size()) put_s(s) ;
}
int new_n(int va){
	int x = ++tot ;
	val(x) = va , rnd(x) = rand() , siz(x) = 1 ;
	return x ;
}
void push_up(int u){
	siz(u) = siz(ls(u))+siz(rs(u))+1 ;
}
void split(int u , int va , int &x , int &y){ // x树中的节点的valmax < y树中的节点的valmin  
	if(!u) return x = y = 0 , void() ;
	if(val(u) <= va){
		x = u ;
		split(rs(x) , va , rs(x) , y) ;
		push_up(x) ;
	}else{
		y = u ;
		split(ls(y) , va , x , ls(y)) ;
		push_up(y) ;
	}
}
int merge(int x , int y){ // x树中的节点的valmax < y树中的节点的valmin 
	if(!x || !y) return x+y ;
	if(rnd(x) < rnd(y)){
		rs(x) = merge(rs(x) , y) ;
		return push_up(x) , x ;
	}else{
		ls(y) = merge(x , ls(y)) ;
		return push_up(y) , y ;
	}
}
void insert(int va){
	int x , y ; new_n(va) ;
	split(root , va , x , y) ;
	root = merge(merge(x , new_n(va)) , y) ;
}
void del(int va){
	int x , y , z ;
	split(root , va , x , z) ;
	split(x , va-1 , x , y) ;
	y = merge(ls(y) , rs(y)) ;
	root = merge(merge(x , y) , z) ;
}
int get_val(int u , int k){ // 第k大 
//	cout << u << " " << k << endl ;
	if(siz(ls(u))+1 == k) return val(u) ;
	else if(siz(ls(u)) >= k-1) return get_val(ls(u) , k) ;
	else return get_val(rs(u) , k-siz(ls(u))-1) ; // !!!!!
}
int get_rn(int va){ // va的排名 
	int x , y ; split(root , va-1 , x , y) ;
	int ans = siz(x)+1 ; 
	return root = merge(x , y) , ans ;
} 
int get_p(int va){ // 前驱 
	int x , y ; split(root , va-1 , x , y) ;
//	cout << "ok1\n" ;
	int ans = get_val(x , siz(x)) ;
//	cout << "ok2\n" ;
	return root = merge(x , y) , ans ;
}
int get_s(int va){ // 后继 
	int x , y ; split(root , va , x , y) ;
	int ans = get_val(y , 1) ;
	return root = merge(x , y) , ans ;
} 
int main(){
	srand(time(0)) ;
	read(n) ;
	for(int i = 1 ; i <= n ; i++){
		read(op) , read(x) ;
		if(op == 1) insert(x) ;
		else if(op == 2) del(x) ;
		else if(op == 3) write(get_rn(x) , "\n") ;
		else if(op == 4) write(get_val(root , x) , "\n") ;
		else if(op == 5) write(get_p(x) , "\n") ;
		else write(get_s(x) , "\n") ; 
	}
	return 0 ;
}

2025/1/21 10:51
加载中...