第一个平衡树板子,有旋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. 取消PHPCMS V9后台新版本升级提示信息

    方法非常简单,只要找到文件: phpcms/libs/classes/update.class.php 文件,修改第50行的代码(大概位置): function notice() { return $ ...

  2. Vulkan Tutorial 23 Descriptor layout and buffer

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 我们现在可以将任意属性传递给每个顶点的顶点着色器使用.但是 ...

  3. 《JavaScript高级程序设计》笔记二

    第二章 在HTML中使用JavaScript 要想把JavaScript放到网页中,就必须涉及到Web的核心语言HTML.向HTML页面中插入JavaScript的主要方法,就是使用<scrip ...

  4. 【Python3之异常处理】

    一.错误和异常 1.错误 代码运行前的语法或者逻辑错误 语法错误(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正) def test: ^ SyntaxError: inva ...

  5. Intellj IDEA光标为insert状态,无法删除内容

    以前用得是社区版的IDEA,今天装了14版本的,结果导入项目后,发现打开java文件的光标是win系统下按了insert键后的那种宽的光标,并且还无法删除内容,且按删除(delete)键也只见光标往前 ...

  6. Java编码问题汇总

    转自 http://www.blogjava.net/zhangchao/archive/2011/05/26/351051.html Thanks Java编码问题汇总 工作中经常遇到java编码问 ...

  7. html网页的兼容性和css优先级

    网页不仅是在一个浏览器上显示的网页,也要多考虑其他浏览器的兼容性,火狐.谷歌.搜狗等浏览器总体来说,网页的变化不大,最主要的是还是IE浏览器. color:red\9; IE6  IE7   IE8  ...

  8. accp8.0转换教材第9章JQuery相关知识理解与练习

    自定义动画 一.单词部分: ①animate动画②remove移除③validity有效性 ④required匹配⑤pattern模式 二.预习部分 1.简述JavaScript事件和jquery事件 ...

  9. Oracle 使用命令导入dmp文件

    若要导入到特定的表空间则需要新建表空间,若不要求,则用已有的,则只需执行下面的步骤 在dos窗口中输入imp 用户名/密码@ip地址:端口号/数据库实例 file='需要导入的dmp文件的路径' fu ...

  10. Linux的同步访问技术

    1.中断屏蔽: 单CPU范围内避免竞态的一种简单方法:在进入临界区之前屏蔽系统的中断.中断屏蔽将使得中断与进程之间的并发不再发生,而且Linux内核的进程调度等操作都依赖中断来实现,内核抢占式进程之间 ...