BST-Treap名次树指针实现板子 Ver2.1

这篇具有很好参考价值的文章主要介绍了BST-Treap名次树指针实现板子 Ver2.1。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

为了更好的阅读体验,请点击这里

这里只有板子没有原理QWQ

可实现

1.插入 x 数

2.删除 x 数(若有多个相同的数,只删除一个)

3.查询 x 数的排名(排名定义为比当前数小的数的个数 +1)

4.查询排名为 x 的数

5.求 x 的前驱(前驱定义为小于 x,且最大的数)

6.求 x 的后继(后继定义为大于 x,且最小的数)

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

在 Ver1.0 基础上把指针板子修正成 C++ 的类方法版本了,null 指针使用 static 静态量来处理。然后仅需要实现类的方法中包含小于号的重载就可以使用这个名次树了。另外,这里所有涉及到的名次都是 1-index 的。

目前还有迭代器、\(O(n)\) 建树没有实现,剩下的功能都有所实现。查询排名为 \(x\) 的数如果 \(x \not \in [1, sz_{root}]\)RE,前驱和后继如果不存在会返回 null->v。这个实现有点脑浆,所以可能以后还会改。

请务必不要使用 std::swap 直接交换两个 Treap否则会析构删得什么都不剩!取而代之,可以使用成员函数中的 swap文章来源地址https://www.toymoban.com/news/detail-711546.html

#include <bits/stdc++.h>
using namespace std;

template<class T> class Treap {
public:
	Treap() {}
	~Treap() { _clear(root);}
	void insert(T x) { _insert(root, x);}
	void erase(T x) { _erase(root, x);}
	int rank(T x) { return _GetRankOfVal(root, x);}
	T kth(int x) { assert(1 <= x && x <= root->sz); return _GetValOfRank(root, x);}
	T pre(T x) { Node *ans = null; query_pre(root, x, ans); return ans->v;}
	T nxt(T x) { Node *ans = null; query_nxt(root, x, ans); return ans->v;}
	bool empty() { return root->sz == 0;}
	int size() { return root -> sz;}
	void clear() { _clear(root);}
    void swap(Treap<T>& rhs) { std::swap(root, rhs.root);}

private:
	struct Node {
		Node *ch[2];
		T v;
		int sz, r, cnt;
		Node() { sz = r = cnt = 0;}
		Node(const T &v):v(v) { ch[0] = ch[1] = null; r=rand(); sz = cnt = 1;}
		bool operator < (const Node& rhs) const { return r < rhs.r;}
		int cmp(const T& x) const {
			if(!(x < v || v < x)) return -1;
			return v < x;
		}
		void upd() { sz = ch[0] -> sz + ch[1] -> sz + cnt;}
	};
	static Node *null;
	Node *root = null;

	void rotate(Node* &o, const int &d) {
		Node *k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o;
		o->upd(); k->upd(); o = k;
	}
	void _insert(Node* &o, const T &x) {
		if (o == null) { o = new Node(x); return;}
		o->sz++;
		int d = o->cmp(x);
		if (d == -1) {o->cnt++; return;}
		_insert(o->ch[d], x);
		if (o->r < o->ch[d]->r) rotate(o, d^1);
		o -> upd();
	}
	void _erase(Node* &o, const T &x) {
		if (o == null) return;
		int d = o->cmp(x);
		if (d == -1) {
			Node* u = o;
			if (o->cnt > 1) {o->cnt--; o->sz--; return;}
			if (o->ch[0] != null && o->ch[1] != null) {
				int d2 = o->ch[0]->r > o->ch[1]->r;
				rotate(o, d2); _erase(o->ch[d2], x);
			}
			else {
				if (o->ch[0] == null) o = o->ch[1]; else o = o->ch[0];
				delete u;
			}
		}
		else _erase(o->ch[d], x);
		if(o != null) o->upd();
	}
	int _GetRankOfVal(Node *&o, const T &x) {
		if (o == null) return 1;
		if (!(o->v < x || x < o->v)) return o->ch[0]->sz + 1;
		else if (o->v < x) return o->ch[0]->sz + o->cnt + _GetRankOfVal(o->ch[1], x);
		else return _GetRankOfVal(o->ch[0], x);
	}
	T _GetValOfRank(Node *&o, const int &k) {
		if (o == null) return T();
		if (!(o->ch[0]->sz < k)) return _GetValOfRank(o->ch[0], k);
		else if(o->ch[0]->sz + o->cnt < k)
			return _GetValOfRank(o->ch[1], k - o->ch[0]->sz - o->cnt);
		return o->v;
	}

	void query_pre(Node *&o, const T &x, Node *&ans) {
		if (o == null) return;
		if (o->v < x) { ans = o; query_pre(o->ch[1], x, ans);}
		else query_pre(o->ch[0], x, ans);
	}
	void query_nxt(Node *&o, const T &x, Node *&ans) {
		if (o == null) return;
		if (x < o->v) { ans = o; query_nxt(o->ch[0], x, ans);}
		else query_nxt(o->ch[1], x, ans);
	}
	void _clear(Node*& o) {
		if (o == null || o == NULL) return;
		_clear(o -> ch[0]); 
		_clear(o -> ch[1]);
        delete o;
        return;
	}
};
template<class T> typename Treap<T>::Node* Treap<T>::null = new Node();

struct AAA {
	int a;
	// AAA(int a = 0):a(a) {}
	bool operator < (const AAA& rhs) const {
		return a < rhs.a;
	}
};

int main() {
#ifdef LOCAL
	freopen("test.in", "r", stdin);
#endif
	int n; scanf("%d",&n);
    int op,y;
	Treap<AAA> S;
    for(int i=0;i<n;i++) {
        scanf("%d%d",&op,&y);
		AAA x = AAA{y};
        switch(op) {
            case 1: S.insert(x); break;
            case 2: S.erase(x); break;
            case 3: printf("%d\n",S.rank(x)); break;
            case 4: printf("%d\n",S.kth(y).a); break;
            case 5: printf("%d\n",S.pre(x).a); break;
            case 6: printf("%d\n",S.nxt(x).a); break;
        }
    }
	return 0;
} 

到了这里,关于BST-Treap名次树指针实现板子 Ver2.1的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 把unc0ver.ipa重签名后安装到手机上实现越狱2023年4月15日更新

    前提,需要自己拥有开发者证书才能重签名uncover.ipa实现越狱 使用爱思助手一键越狱以后总提示正在\\\"生成安装包\\\",后来我去了uncover的官网,.下载了ipa包,把uncover.ipa用爱思助手安装到手机上,提示缺少appsync补丁,我试了一下不行. 第二种方法提示要安装AltServer,我安装上了,但是提示

    2024年02月11日
    浏览(47)
  • FHQ-Treap(非旋treap/平衡树)——从入门到入坟

           作者:hsez_yyh        链接: FHQ-Treap——从入门到入坟_hsez_yyh的博客-CSDN博客        来源:湖北省黄石二中信息竞赛组        著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。         平衡树有很多种,其中 fhq-treap 可以说是最

    2024年02月16日
    浏览(37)
  • FHQ-Treap

    模板传送 FHQ-Treap顾名思义就是范浩强大佬设计的一种二叉平衡树 下面我们来讲一下它的原理和代码 对于一个节点,我们需要记录的是 对应的值 子树节点数 左右孩子编号 对应的随机值 看到这里有人疑惑了,这个 对应的随机值 是怎么回事啊? 这里就涉及到了一个FHQ-Treap里

    2024年02月07日
    浏览(28)
  • FHQ Treap学习笔记

    前置芝士(了解即可啦~):C++、BST 二叉搜索树、堆、二叉堆 Treap 树堆,即树(Tree)+堆(Heap),是一棵 弱平衡 的二叉搜索树(BST),能同时满足 二叉搜索树 与 堆 的性质。 BST 满足任意一个节点的权值都大于等于左子树所有点的权值,且小于等于右子树所有点的权值的性

    2024年02月05日
    浏览(74)
  • C语言:猜名次

    5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:              A 选手说: B第二 , 我第三 ; B 选手说: 我第二 , E第四 ; C 选手说: 我第一 , D第二 ; D 选手说: C最后 , 我第三 ; E 选手说: 我第四 , A第一 ; 比赛结束后,每位选手 都说对了一半 ,请

    2024年02月13日
    浏览(26)
  • 【数学建模】离散模型(循环比赛的名次)

    问题描述 若干支球队参加单循环比赛,各队两两交锋,假设每场比赛只计胜负,不计比分,且不允许平局。在循环赛结束后怎样根据他们的比赛结果排列名次呢? 一种表述比赛结果的办法是,用图的顶点表示球队,用连接两个顶点的、有方向的边表示两支球队的比赛结果,

    2024年02月08日
    浏览(64)
  • 找凶手,定名次,字符串旋转,杨氏矩阵

    1.找凶手问题: //题目名称: //猜凶手 //题目内容: //日本某地发生了一件谋杀案,警察通过排查确定凶手必为4个嫌疑犯的一个。 //以下为4个嫌疑犯的供词: //A说:不是我 //B说:是C //C说:是D //D说:C在胡说 //已知3个人说的是真话,1个人说的是假话。 //请根据这些信息,写

    2023年04月23日
    浏览(34)
  • Atcoder Beginner Contest 324 G Generate Arrays 题解-Treap

    为了更好的阅读体验,请点击这里 题目链接 套上平衡树板子就能做的很快的题,然后因为是指针存树,因此交换只需要把序列大小较小的挨个拿出来插到相应的地方即可。复杂度 (O(N log^2 N)) 。 但是一定要记住 不可以直接使用 std::swap 交换包含带有指针的类的实例(如代码

    2024年02月08日
    浏览(43)
  • 倒置字符串、猜名次、猜凶手、杨辉三角

    目录   例一:倒置字符串 例二:猜名次 例三:猜凶手 例四:杨辉三角 方法一  方法二    首先我们先来看一下题目具体要求 再来看一下我们所需要的效果  这里呢,博主给出两种思路,一种是先将整个字符串逆序,再将单个单词逆序;另一种是先将单个单词厉旭,再将整

    2024年02月06日
    浏览(40)
  • 【C语言】【典例详解】【刷题】猜名次&&猜凶手【循环练习】

    目录 猜名次问题 典例题目 题目分析: 代码实现: 运行结果: 猜凶手问题  典例题目 题目分析 代码实现: 运行结果: 猜名次: 5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果: A选手说:B第二,我第三; B选手说:我第二,E第四; C选手说:我第一,D第二;

    2024年02月07日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包