第一个平衡树板子,有旋Treap。用随机函数规定一个堆,维护点权的同时维护堆的性质,可以有效地避免退化成链。按我的理解,建立一棵二叉排序树,树的形态会和给出节点的顺序有关。按照出题人很机智定理,数据肯定不会太容易操作,这时候就需要我们自行调整“数据顺序”,平衡树应运而生。

这个板子涵盖的操作有左旋、右旋(维护堆性质)、添加节点、删除节点(建树相关)、查找第x个元素、查找元素排名、查找前驱、查找后继这8种操作。改变树本身的操作都是取地址传参的,询问操作则都是简单传参。原理不是太难理解,应用则看以后刷题了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
using namespace std;
const int sj=;
int n,opt,g,jg,cs,size;
struct tree
{
int l,r,v,w,rnd,size;
}t[sj];
void update(int x)
{
t[x].size=t[t[x].l].size+t[t[x].r].size+t[x].w;
}
void lturn(int &x)
{
int tt=t[x].r;
t[x].r=t[tt].l;
t[tt].l=x;
t[tt].size=t[x].size;
update(x);
x=tt;
}
void rturn(int &x)
{
int tt=t[x].l;
t[x].l=t[tt].r;
t[tt].r=x;
t[tt].size=t[x].size;
update(x);
x=tt;
}
void cr(int &x,int y)
{
if(x==)
{
size++;
x=size;
t[x].size=t[x].w=;
t[x].v=y;
t[x].rnd=rand();
return;
}
t[x].size++;
if(t[x].v==y) t[x].w++;
else if(y>t[x].v)
{
cr(t[x].r,y);
if(t[t[x].r].rnd<t[x].rnd) lturn(x);
}
else
{
cr(t[x].l,y);
if(t[t[x].l].rnd<t[x].rnd) rturn(x);
}
}
void sc(int &k,int x)
{
if(k==) return;
if(t[k].v==x)
{
if(t[k].w>)
{
t[k].w--;
t[k].size--;
return;
}
if(t[k].l*t[k].r==) k=t[k].l+t[k].r;
else if(t[t[k].l].rnd<t[t[k].r].rnd)
rturn(k),sc(k,x);
else
lturn(k),sc(k,x);
}
else if(x>t[k].v)
t[k].size--,sc(t[k].r,x);
else
t[k].size--,sc(t[k].l,x);
}
int query_rank(int k,int x)
{
if(k==) return ;
if(t[k].v==x) return t[t[k].l].size+;
else if(x>t[k].v)
return t[t[k].l].size+t[k].w+query_rank(t[k].r,x);
else return query_rank(t[k].l,x);
}
int query_num(int k,int x)
{
if(k==) return ;
if(x<=t[t[k].l].size)
return query_num(t[k].l,x);
else if(x>t[t[k].l].size+t[k].w)
return query_num(t[k].r,x-t[t[k].l].size-t[k].w);
else return t[k].v;
}
void query_pre(int k,int x)
{
if(k==) return;
if(t[k].v<x)
jg=k,query_pre(t[k].r,x);
else query_pre(t[k].l,x);
}
void query_sub(int k,int x)
{
if(k==) return;
if(t[k].v>x)
jg=k,query_sub(t[k].l,x);
else query_sub(t[k].r,x);
}
int main()
{
//freopen("t.txt","r",stdin);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d%d",&opt,&cs);
if(opt==)
cr(g,cs);
if(opt==)
sc(g,cs);
if(opt==)
printf("%d\n",query_rank(g,cs));
if(opt==)
printf("%d\n",query_num(g,cs));
if(opt==)
{
jg=;
query_pre(g,cs);
printf("%d\n",t[jg].v);
}
if(opt==)
{
jg=;
query_sub(g,cs);
printf("%d\n",t[jg].v);
}
}
//while(1);
return ;
}

种下一棵树:有旋Treap的更多相关文章

  1. 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)

    原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...

  2. 替罪羊树&&非旋treap

    题解: 替罪羊树的模板和splay差距还是比较大的.. 按照我的splay的写法 真是都是问题.. 替罪羊树就是暴力的搞 当某颗子树大小大于这棵树的alpha时 就退出 另外删除的时候打懒标记删除 当 ...

  3. [转载]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)

    转载自ZZH大佬,原文:http://www.cnblogs.com/LadyLex/p/7182491.html 今天我们来学习一种新的数据结构:无旋treap.它和splay一样支持区间操作,和t ...

  4. [您有新的未分配科技点]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)

    今天我们来学习一种新的数据结构:无旋treap.它和splay一样支持区间操作,和treap一样简单易懂,同时还支持可持久化. 无旋treap的节点定义和treap一样,都要同时满足树性质和堆性质,我 ...

  5. 2017年陕西省网络空间安全技术大赛——种棵树吧——Writeup

    2017年陕西省网络空间安全技术大赛——种棵树吧——Writeup 下载下来的zip解压得到两个jpg图片,在Kali中使用binwalk查看文件类型如下图: 有两个发现: 1111.jpg 隐藏了一 ...

  6. [模板] 平衡树: Splay, 非旋Treap, 替罪羊树

    简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...

  7. Trees in a Wood. UVA 10214 欧拉函数或者容斥定理 给定a,b求 |x|<=a, |y|<=b这个范围内的所有整点不包括原点都种一棵树。求出你站在原点向四周看到的树的数量/总的树的数量的值。

    /** 题目:Trees in a Wood. UVA 10214 链接:https://vjudge.net/problem/UVA-10214 题意:给定a,b求 |x|<=a, |y|&l ...

  8. 非旋treap套线段树

    BZOJ3065. 去年用pascal 块链过了.. 今年来试了试非旋treap大法   注定被块链完爆 代码留这. 第一份 :辣鸡的  垃圾回收做法  跑得极慢 #include <bits/ ...

  9. [转载]无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )

    转自ZZH大佬,原文:http://www.cnblogs.com/LadyLex/p/7182631.html 1500: [NOI2005]维修数列 Time Limit: 10 Sec  Mem ...

随机推荐

  1. vue 基础-->进阶 教程(2): 指令、组件

    第二章 建议学习时间4小时  课程共3章 前面的nodejs教程并没有停止更新,因为node项目需要用vue来实现界面部分,所以先插入一个vue教程,以免不会的同学不能很好的完成项目. 本教程,将从零 ...

  2. 【Android Developers Training】 47. 序言:拍摄照片

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  3. spring的Convert机制

    spring.core包内有Converter接口,方法是T convert(S source);从一个类型转为内容一个类型的实际转化器:converters可能非常多,需要一个注册器来集中管理使用, ...

  4. 把本地git仓库中的项目引入到码云上

    一.安装git软件和TortoiseGit客户端(git需配置环境变量,但安装时已经配置好,无需考虑) 二.生成公钥和私钥(建立与码云的连接) 三.在码云上新建项目(建议在组织的基础上)   四.在码 ...

  5. accp8.0转换教材第6章连接MySQL理解与练习

    JDBC_ODBC,纯java方式连接mysql 1.单词部分 ①JDBCjava连接数据库②driver manager驱动③connection连接④statement声明 ⑤execute执行⑥ ...

  6. SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装

    SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装 >>>>>>>& ...

  7. vijos1027题解

    题目: 当大家在考场中接受考验(折磨?)的时候,小呆正在悠闲(欠扁)地玩一个叫"最初梦想"的游戏.游戏描述的是一个叫pass的有志少年在不同的时空穿越对抗传说中的大魔王chines ...

  8. win10 运行sqlplus报错“SP2-1503: 无法初始化 Oracle 调用界面”

    解决方法: 1.临时方案:此时可以以“管理员身份”运行cmd,然后再执行sqlplus就行了. 长久方案: 请看原文:http://blog.csdn.net/bisal/article/detail ...

  9. Qt中使用CEF(Windows下)

    最近项目中要在Qt中使用CEF(Chromium Embedded Framework),在这里总结下其中的几个要点. 下载合适的CEF版本 关于CEF的简介我们这里就不做介绍了,下载CEF可以有2种 ...

  10. 迭代器 Iterator

    迭代器 Iterator 2016-5-7 可以这样说,迭代器统一了对容器的访问方式. 考虑这样的情景:原本是对着List编码,但是后来发现需要把相同的代码用于Set.我们需要一种不关心容器类型 而能 ...