ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

fhq treap 范浩强平衡树

2020-11-07 11:04:26  阅读:346  来源: 互联网

标签:node val merge int fhq tree treap 范浩强 root


https://www.luogu.com.cn/problem/P3369

随机大法好啊啊啊

插入数字的时候,把平衡树按x分裂,插入x后再合并,具体可以看代码

 

#include<iostream>
#include<algorithm> 
#include<cstdio>
#include<ctime>
#include<stack>
using namespace std;
const int maxn = 2e6+10;
struct Node{
	int l,r;
	int val,key;
	int siz;
}tree[maxn];

int l,r,cnt,p,x,n;



void update(int node){
	tree[node].siz = tree[tree[node].l].siz + tree[tree[node].r].siz + 1;
}


void split(int node,int x,int& l,int& r){//node分裂成l和r,l--val<= x   r--val > x     
	if(node == 0){
		l = r = 0;
		return ;
	}
	if(tree[node].val <= x){//左边部分 
		l = node;
		//左边儿子改了,继续分右边
		split(tree[node].r,x,tree[node].r,r); 
	}
	else{
		r = node;
		split(tree[node].l,x,l,tree[node].l); 
	}
	update(node);
}



int add(int val){
	cnt++;
	tree[cnt].siz = 1;
	tree[cnt].l = tree[cnt].r = 0;
	tree[cnt].val = val;
	tree[cnt].key = rand();
	
}




int merge(int l,int r){
	if(!l || !r) return l + r;//总有一个是叶子
	
	if(tree[l].key <= tree[r].key){//l做父亲 ,r比l大,所以r接上l的右子树 
		tree[l].r = merge(tree[l].r,r);
		update(l);
		return l; 
	} 
	else{
		tree[r].l = merge(l,tree[r].l);
		update(r);
		return r;
	}
}


int kth(int node,int k){//排名第k的数字 
	if(k <= tree[tree[node].l].siz){
		return kth(tree[node].l,k);
	} 
	else if(tree[tree[node].l].siz + 1 == k){
		return node;
	}
	else{
		k -= tree[tree[node].l].siz + 1;
		return kth(tree[node].r,k);
	}
}

//int kth(int u,int k)
//{//求排名第k的数
//	if(k<=tree[tree[u].l].siz)//在左区间 
//		return kth(tree[u].l,k);
//	else if(k==tree[tree[u].l].siz+1)//这个数为此区间的根 
//			return u;
//	else
//	{
//		k-=(tree[tree[u].l].siz+1);//排名为k要减少左儿子的节点数 
//		return kth(tree[u].r,k);//在右区间 
//	}
//}




int main(){
	int n;
	scanf("%d",&n);
	int root = 0;
	int p;
	
	srand((unsigned)time(NULL));
	
	while(n--){
		int op,x;
		scanf("%d %d",&op,&x);
		if(op == 1){
			split(root,x,l,r);// node分裂成l和r,l--val<= x   r--val > x     
			add(x);
			root = merge(merge(l,cnt),r); 
		}
		else if(op == 2){//删除x 
			split(root,x,l,r);
			split(l,x-1,l,p);
			
			p = merge(tree[p].l,tree[p].r);//可能有多个x 
			root = merge(merge(l,p),r);
		}
		else if(op == 3){//查询x的排名 
			split(root,x-1,l,r);
			printf("%d\n",tree[l].siz+1);//小于x的个数 
			root = merge(l,r);
		}
		else if(op == 4){//排名为x的数,记录重复 
			printf("%d\n",tree[kth(root,x)].val); 
		}
		else if(op == 5){
			split(root,x-1,l,r);
			
			printf("%d\n",tree[kth(l,tree[l].siz)].val);
			root = merge(l,r);
		}
		else{
			split(root,x,l,r);
			
			printf("%d\n",tree[kth(r,1)].val);
			
			root = merge(l,r);
		}
	}
	return 0;
	
}

  

标签:node,val,merge,int,fhq,tree,treap,范浩强,root
来源: https://www.cnblogs.com/lesning/p/13940182.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有