fhq Treap模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
using namespace std;
struct treap_node{
	treap_node *left,*right;
	int wgt,size,fix; char val;
	treap_node(char val): val(val) {left=right=NULL; size=wgt=1; fix=rand(); }
	int lsize()
	  {
	    if (left)
	      return left->size;
	    else
	      return 0;
	  }
	int rsize()
	  {
	    if (right)
	      return right->size;
	    else
	      return 0;
	  }
	void Maintain()
	  {
	    size=wgt;
	    size+=lsize()+rsize();
	  }
};
int n;
treap_node *root;
typedef pair <treap_node*,treap_node*> droot;
 treap_node *merge(treap_node *a,treap_node *b)
{
	if (!a) return b; if (!b) return a;
	if (a->fix<b->fix)
	  {
	    a->right=merge(a->right,b);
	    a->Maintain();
	    return a;
	  }
	else
	  {
	    b->left=merge(a,b->left);
	    b->Maintain();
	    return b;
	  }
}
droot split(treap_node *x,int k)
{
	if (!x) 
	  return droot(NULL,NULL);
	droot y;
	if (x->lsize()>=k)
	  {
	    y=split(x->left,k);
		x->left=y.second;
		x->Maintain();
		y.second=x; 
	  }
	else
	  {
	    y=split(x->right,k-x->lsize()-1);
	    x->right=y.first;
        x->Maintain();
        y.first=x;
	  }
	return y;
}
void insert(int k,int l)//从第k位插入l位
{
	droot y; char c; int i;
	treap_node *temp;
	y=split(root,k-1);
	for (i=1;i<=l;++i)
	  {
	  	scanf("%c",&c);
	  	while (c<32||c>126)
          scanf("%c",&c);
	  	temp=new treap_node(c);
	    y.first=merge(y.first,temp);
	  }
	root=merge(y.first,y.second);
}
void del(int k,int l)//从第k位删除l位
{
	droot a,b;
	a=split(root,k-1);
	b=split(a.second,l);
	root=merge(a.first,b.second);
}

其他:与线段树类似,reverse和make_same类操作需要打标记并逐层pushdown,min,max等需要updata到root。

### FHQ Treap 数据结构概述 FHQ Treap 是一种无需旋转操作即可保持平衡的二叉查找树(BST),其特性在于既遵循 BST 的性质,即对于任意节点 \(N\),左子树上的所有键值均小于该节点的键值而右子树上的所有键值则都更大;同时也维持着堆的属性——每个节点拥有一个额外分配给它的优先级(通常通过随机数生成),使得父节点总是有着不低于子女们的优先级别[^1]。 这种双重约束确保了即使是在最坏情况下插入序列也能接近理想的对数时间复杂度性能表现。具体而言,当构建一棵由 \(n\) 个互异关键字组成的 FHQ Treap 并且这些关键字对应的优先级被独立均匀分布赋予时,则此树的高度预期大约为 \(\log{n}\)[^3]。 ### FHQ Treap 基本操作解析 #### 插入 Insertion 为了向 FHQ Treap 中添加新元素,在找到合适位置之后并非简单地创建新的叶子节点而是利用分裂(split)与合并(merge)机制完成: - **Split**: 将现有树依据目标数值切割成两部分; - **Merge**: 新建含待插值及其随机化后的高优先生存概率的新根节点连接两侧分割所得之子树形成更新版整体结构。 ```cpp void insert(int& root, int value){ if (!root){ root = new_node(value); return; } int L, R; split(root, value, L, R); root = merge(L, merge(new_node(value), R)); } ``` 这里 `new_node` 函数负责初始化带有指定 key 和随即产生的 priority 的全新节点实例[^4]。 #### 删除 Deletion 移除特定项的过程同样依赖上述提到的基础组件: - 首先定位到需删除的目标节点; - 接下来执行 Split 来分离出含有目标节点的小范围区间; - 最终借助 Merge 方法重组剩余片段而不保留已被剔除的部分。 ```cpp void erase(int& root, int value){ if (!root) return; int L, M, R; split(root, value - 1, L, R); // 左边全部小于value split(R, value, M, R); // 右边全部大于value root = merge(L, R); // 不再包含M中的target node } ``` 以上代码展示了如何高效安全地处理动态集合内的成员变更请求,同时维护良好的渐近运行效率[^5]。 ### 关联功能展示 除了基础 CRUD 外,FHQ Treap 还支持诸如查询第 k 小/大元素、统计某个范围内共有多少条目等高级应用接口的设计实现。这类扩展性得益于灵活运用内部提供的辅助工具函数如 `split()` 和 `merge()`, 它们允许开发者轻松操纵整棵树或其中一部分的状态变化以适应各种实际需求场景下的算法逻辑编写工作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值