首页 > 其他分享 >随用随取的无旋Treap板子!

随用随取的无旋Treap板子!

时间:2024-08-13 16:16:17浏览次数:3  
标签:int 无旋 long Treap lson il siz 随取 root

使用说明及注意事项:

  1. 使用命名空间+结构体进行封装,使用时只需jser::Treapusing namespace jser即可。例如:
/*
way 1
*/
using namespace jser;
Treap tree;
/*
way 2
*/
jser::Treap tree;
  1. 随机数生成采用random_devicemt19937,在某些评测姬上可能不适用,可以换用rand(注意数据范围)或手写随机数生成器。
  2. 使用数据范围宏定义,在结构体开头有数组大小N的宏定义,方便大家修改数据范围。
  3. 多处使用register,C++17及以上不适用,记得更换。
  4. 存储数值为int类,注意是否需要开long long

功能介绍

  1. void push(int x)加入一个 \(x\) 值。
  2. void pop(int x)删除一个 \(x\) 值。
  3. int rank(int x)返回 \(x\) 在数列里的排名。
  4. int kth(int x)返回在数列中排名为 \(x\) 的数值。
  5. int pre(int x)返回数值 \(x\) 在数列中的前驱。如果没有,返回负无穷。
  6. int next(int x)返回数值 \(x\) 在数列中的后继。如果没有,返回正无穷。

代码时刻

教授の全局宏定义(不喜可换):

#define il inline
#define ri register int
#define inf 0x3f3f3f3f

正片:

namespace jser
{
	random_device rd;
	long long sed=rd();
	mt19937 rad(time((time_t*)&sed));
	il long long getrand(long long x,long long y)
	{
		return rad()%(y-x+1)+x;
	}
	struct Treap
	{
		#define N 200002
		int root,cnt;
		int val[N],siz[N],pri[N],lson[N],rson[N];
		il void pushup(int x)
		{
			siz[x]=siz[lson[x]]+siz[rson[x]]+1;
		}
		il int merge(int x,int y)
		{
			if(!x||!y)
			{
				return x|y;
			}
			if(pri[x]<pri[y])
			{
				rson[x]=merge(rson[x],y);
				pushup(x);
				return x;
			}
			else
			{
				lson[y]=merge(x,lson[y]);
				pushup(y);
				return y;
			}
		}
		il pair<int,int>split(int x,int y)
		{
			if(!x)
			{
				return {0,0};
			}
			ri ls=lson[x],rs=rson[x];
			if(y==siz[ls])
			{
				lson[x]=0;
				pushup(x);
				return {ls,x};
			}
			if(y==siz[ls]+1)
			{
				rson[x]=0;
				pushup(x);
				return {x,rs};
			}
			pair<int,int>rn;
			if(y<siz[ls])
			{
				rn=split(ls,y);
				lson[x]=rn.second;
				pushup(x);
				return {rn.first,x};
			}
			else
			{
				rn=split(rs,y-siz[ls]-1);
				rson[x]=rn.first;
				pushup(x);
				return {x,rn.second};
			}
		}
		il int rank(int x)
		{
			ri y=root,rn=inf,z=0;
			while(y)
			{
				if(x==val[y])
				{
					rn=min(rn,z+siz[lson[y]]+1);
				}
				if(x<=val[y])
				{
					y=lson[y];
				}
				else
				{
					z+=siz[lson[y]]+1;
					y=rson[y];
				}
			}
			if(rn==inf)
			{
				return z;
			}
			return rn;
		}
		il int kth(int x)
		{
			ri y=root;
			while(1)
			{
				if(siz[lson[y]]==x-1)
				{
					return val[y];
				}
				if(siz[lson[y]]>x-1)
				{
					y=lson[y];
				}
				else
				{
					x-=siz[lson[y]]+1;
					y=rson[y];
				}
			}
		}
		il int pre(int x)
		{
			ri y=root,rn=-inf;
			while(y)
			{
				if(val[y]<x)
				{
					rn=val[y];
					y=rson[y];
				}
				else
				{
					y=lson[y];
				}
			}
			return rn;
		}
		il int next(int x)
		{
			ri y=root,rn=inf;
			while(y)
			{
				if(val[y]>x)
				{
					rn=val[y];
					y=lson[y];
				}
				else
				{
					y=rson[y];
				}
			}
			return rn;
		}
		il void push(int x)
		{
			ri y,rks=rank(x);
			pair<int,int>qwer=split(root,rks);
			cnt++;
			y=cnt;
			val[y]=x;
			pri[y]=rad();
			siz[y]=1;
			root=merge(qwer.first,cnt);
			root=merge(root,qwer.second);
		}
		il void pop(int x)
		{
			ri rks=rank(x);
			pair<int,int>q=split(root,rks),p;
			p=split(q.first,rks-1);
			root=merge(p.first,q.second);
		}
		#undef N
	};
}

标签:int,无旋,long,Treap,lson,il,siz,随取,root
From: https://www.cnblogs.com/ywhhdjser-97/p/18357190

相关文章

  • 「FHQ-Treap —— 码量最小的平衡树」学习笔记
    不同于普通Treap,FHQ-Treap不需要左旋和右旋操作来处理数据。因此FHQ-Treap也称作无旋Treap。FHQ-Treap是基于Split(分裂)和Merge(合并)两种操作的平衡树。其与普通Treap的原理完全不同。一些基础的操作:例如Insert(插入元素)和Delete(删除元素)。对于Insert(插入元素),新建一......
  • 怎么优雅的踩爆 Treap
    在发布了文章Treap学习笔记后我认为我的平衡树能力已经登峰造极了。但是Treap真tmd太难写了,所以我们的czy大佬开发除了一种可以优雅的踩爆Treap的绝佳方案。#include<bits/stdc++.h>usingnamespacestd;intn;structtree{ vector<int>v; voidadd(intx){v.in......
  • FHQ_Treap
    先记个板子#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+5;intn;intrt,son[N][2],sz[N],va[N],pri[N],tot;structFHQ{ voidpushup(intx){sz[x]=sz[son[x][0]]+sz[son[x][1]]+1;} intmerge(intx,inty) { if(!x||!y)returnx|y; if......
  • 【备忘录】家里的台式机做随用随开,随用随取的服务器。IPv6的方式
    ipv6既然能给沙子配上地址,那么我的闲置pc为什么就不能配上地址呢?带着疑问,我开启了这个电脑随用随开,资料随用随取的魔幻之旅。前期准备:oray公司的向日葵开机棒(85元)、一台支持wakeonlan的windows旧电脑、一台支持wakeonlan的linux旧电脑、一台有网络的租赁主机(150元/年)、python语......
  • FHQ treap(再见splay------)
    但凡打过平衡树的应该都知道\(\huge{二逼平衡树}\)这道题,抄了两个小时的splay版题解,然后发现了\(\color{maroon}FHQtreap\):$\large\color{green}这是splay$structjjtree{ inlinevoidup(rintx){sz[x]=sz[son[x][0]]+sz[son[x][1]]+cnt[x];} inlineboolso(rintx){retu......
  • 平衡樹專題Treap
    前言:题单在此:HL平衡树0701-题单-洛谷|计算机科学教育新生态(luogu.com.cn)平衡树什么是平衡树?首先我们需要知道二叉查找树的内容。二叉查找树(BST:BinarySearchTree)首先,他是一棵二叉树其次,他的左子树的权值<根节点的权值<右子树的权值最后,也是最重要的,他的中序遍历......
  • 算法课程笔记——FHQ-Treap(无旋)
    算法课程笔记——FHQ-Treap(无旋)......
  • 平衡树 Treap & Splay [学习笔记]
    平衡树\(\tt{Treap}\)&\(\tt{Splay}\)壹.单旋\(\tt{Treap}\)首先了解\(\tt{BST}\)非常好用的东西,但是数据可以把它卡成一条链\(\dots\)于是,我们将\(\tt{Tree}\)与\(\tt{heap}\)(堆)合并,以保证平衡树\(\log\)的深度。具体地,我们可以使用旋转操作实现K8He的图......
  • 平衡树 Treap & Splay [学习笔记]
    平衡树\(\tt{Treap}\)&\(\tt{Splay}\)壹.单旋\(\tt{Treap}\)首先了解\(\tt{BST}\)非常好用的东西,但是数据可以把它卡成一条链\(\dots\)于是,我们将\(\tt{Tree}\)与\(\tt{heap}\)(堆)合并,以保证平衡树\(\log\)的深度。具体地,我们可以使用旋转操作实现K8He的图......
  • 【老鼠看不懂的数据结构】FHQTreap 初识
    Treap弱平衡的随机性很强的老鼠看不懂的平衡树Q:为什么叫Treap?A:看看二叉搜索树(BST)和堆(Heap),组合起来就是Treap其中,二叉搜索树的性质是:左子节点的值(val)比父节点小右子节点的值(val)比父节点大如果这些节点的值都一样,这棵树就会退化成一颗(?)链。对,我知道你在想......