模板题:D错因见注释

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int INF=0x7fffffff;
struct treap
{
treap* lson;
treap* rson;
int key;//该节点的值
int priority;//优先级
int size;//该节点以及其子树的大小
int cnt;//当前值的数字的个数
int lsize()//返回左子树的大小
{
if (lson==NULL) return ;
else return lson->size;
}
int rsize()//返回右子树的大小
{
if (rson==NULL) return ;
else return rson->size;
} treap()
{
size=cnt=;//这里初始值应该是1而不是0
priority =rand();//随机生成优先级
lson=rson=NULL;
}
};
treap* root=NULL;
int n; void update(treap* &rt)//【【Attention】】要写成*&
{
/*旋转后进行的操作更新size大小=cnt+左子树size+右子树size*/
rt->size=rt->cnt;
rt->size+=rt->lsize();
rt->size+=rt->rsize();
} void RightRotate(treap* &rt)
{
/*画图模拟一下:D*/
treap* tmp=rt->lson;
rt->lson=tmp->rson;
tmp->rson=rt;
update(rt);
update(tmp);
rt=tmp;
} void LeftRotate(treap* &rt)
{
treap* tmp=rt->rson;
rt->rson=tmp->lson;
tmp->lson=rt;
update(rt);
update(tmp);
rt=tmp;
} void insert(treap*&rt,int x)
{
/*
如果当前根节点是空的,那么新建一棵平衡树;
如果当前的x和根节点的数值大小一样,则直接在根节点累加个数;
如果当前x小于根节点的数值,那么向左子树搜索。回溯后如果左边的优先级大于根节点,则右旋
如果当前x小于根节点的数值,那么向右子树搜索。回溯后如果右边的优先级大于根节点,则左旋
*/
if (rt==NULL)
{
rt=new treap;
rt->key=x;
}
else if (x==rt->key)
{
rt->size++;
rt->cnt++;
}
else if (x<rt->key)
{
insert(rt->lson,x);
if (rt->lson->priority>rt->priority) RightRotate(rt);
update(rt);
}
else
{
insert(rt->rson,x);
if (rt->rson->priority>rt->priority) LeftRotate(rt);
update(rt);
}
} void del(treap* &rt,int x)
{
/*
如果当前根节点的key就是要删除的那个值
(1)如果当前数值的个数大于1个,直接减去cnt和size即可;
(2)如果左子树是空的,这将根节点保存给临时变量,根节点等于它的右子树,释放原来根节点内存;
(3)右子树为空同理;
(4)如果左右子树均不为空,比较两者的优先级。如果左子树优先级大则右旋,反之左旋。
如果当前根节点的key不是要删除的那个值
(1)如果x<key,则搜索左子树;
(2) 否则搜索右子树。
*/
if (x==rt->key)
{
if (rt->cnt>)
{
rt->cnt--;
rt->size--;
}
else if (rt->lson==NULL)
{
treap* tmp=rt;
rt=rt->rson;
delete tmp;
}
else if (rt->rson==NULL)
{
treap* tmp=rt;
rt=rt->lson;
delete tmp;
}
else
{
if (rt->lson->priority>rt->rson->priority)
{
RightRotate(rt);
del(rt->rson,x);
}
else
{
LeftRotate(rt);
del(rt->lson,x);
}
}
}
else
{
if (rt->key>x) del(rt->lson,x);
else del(rt->rson,x);
}
if (rt!=NULL) update(rt);
} int getrank(treap* &rt,int x)
{
/*
如果当前的key等于要询问的数,直接返回排名(左子树的大小+1)
如果当前的key大于要询问的数,进入左子树查询并返回排名
如果当前的key小于要询问的树,则返回的排名=(左子树大小+当前节点数的个数+它在右子树中的排名)
*/
if (rt->key==x) return (rt->lsize()+);
if (x<rt->key) return (getrank(rt->lson,x));
return (getrank(rt->rson,x)+rt->lsize()+rt->cnt);
} int getnum(treap* &rt,int x)
{
/*
如果需要询问的排名属于当前节点的范围(左子树个数+1~左子树个数+当前节点数的个数),则直接返回当前的key
如果要询问的排名在左子树,则前往左子树询问排名
如果要询问的排名在右子树,则前往右子树询问排名,且要询问的排名=排名-左子树的大小-当前节点代表的数的个数
*/
if (rt->lsize()+<=x && x<=rt->lsize()+rt->cnt) return rt->key;
if (x<=rt->lsize()) return getnum(rt->lson,x);
return getnum(rt->rson,x-rt->lsize()-rt->cnt);
} int pre(treap* &rt,int x)
/*
如果当前节点的值小于x,则取它和ans中较大的那个,并继续搜索右子树
如果当前节点的值大于等于x,则继续搜索左子树
*/
{
int ans=-INF;
treap* tmp=rt;
while (tmp)
{
if (tmp->key<x)
/*尴尬,这整个子程序的tmp->key都手残敲成了tmp->key...下次注意:D*/
{
ans=max(tmp->key,ans);
tmp=tmp->rson;
}
else tmp=tmp->lson;
}
return ans;
} int suc(treap* &rt,int x)
/*与pre类似*/
{
int ans=INF;
treap* tmp=rt;
while (tmp)
{
if (tmp->key>x)
{
ans=min(tmp->key,ans);
tmp=tmp->lson;
}
else tmp=tmp->rson;
}
return ans;
} void option()
{
int opt,x;
scanf("%d%d",&opt,&x);
if (opt==) insert(root,x);
else if (opt==) del(root,x);
else if (opt==) printf("%d\n",getrank(root,x));
else if (opt==) printf("%d\n",getnum(root,x));
else if (opt==) printf("%d\n",pre(root,x));
else if (opt==) printf("%d\n",suc(root,x));
} void release(treap* &rt)
{
if (rt->lson) release(rt->lson);
if (rt->rson) release(rt->rson);
free(rt);
} int main()
{
scanf("%d",&n);
for (int i=;i<n;i++) option();
release(root);
return ;
}

【Treap模板详细注释】BZOJ3224-普通平衡树的更多相关文章

  1. 【强连通分量】 Kosaraju和Tarjan算法 (标准模板+详细注释)

    codevs 题意:求最大强连通分量的大小以及所包含的顶点有哪些 Tarjan算法 #include<iostream> #include<queue> #include< ...

  2. BZOJ3224普通平衡树——非旋转treap

    题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...

  3. [luogu3369]普通平衡树(treap模板)

    解题关键:treap模板保存. #include<cstdio> #include<cstring> #include<algorithm> #include< ...

  4. Qt5_简易画板_详细注释

    代码下载链接:  http://pan.baidu.com/s/1hsc41Ek 密码: 5hdg 显示效果如下: 代码附有详细注释(代码如下) /*** * 先新建QMainWindow, 项目名称 ...

  5. BZOJ 1588: Treap 模板

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 12171  Solved: 4352 Description ...

  6. 51nod 1126 求递推序列的第N项 思路:递推模拟,求循环节。详细注释

    题目: 看起来比较难,范围10^9 O(n)都过不了,但是仅仅是看起来.(虽然我WA了7次 TLE了3次,被自己蠢哭) 我们观察到 0 <= f[i] <= 6 就简单了,就像小学初中学的 ...

  7. 一套强大的vim配置文件+详细注释

    phpchina折腾王独家配置,灰常牛叉的一套vim配置,另附有详细注释,自己折腾vim的时候可以参照其中的大部分设置进行一些个性化定制."是否兼容VI,compatible为兼容,noco ...

  8. MFC的PNG贴图按钮类(详细注释)

    MFC的PNG贴图按钮类(详细注释) (转载请注明出处) 作者:梦镜谷雨 萌新第二次写帖子,请多多包涵.末尾附上相应代码(PS公司繁体系统所以部分注释繁体请别介意). 因自带控件不美观,于是网上参考学 ...

  9. dedecms首页入口的详细注释

    今天闲来无事,就拿来dede首页的文件给大家详细解释一遍,以便于新手学习,注释过程非常非常非常的详细,里面解释到dede表前缀#@__代替的原理.解释到dede很多自定义函数的具体位置和具体作用等等疑 ...

随机推荐

  1. MongoDB加索引

    1.登陆MongoDB, 命令行在MongoDB主目录下执行:mongo -port 27017 2.切换至需要添加索引的db 并授权 use MeetingBooking db.auth({&quo ...

  2. mysql_存储过程和函数

    存储过程和函数 1.什么是存储过程和函数 存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句集合,调用存储过程和函数可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对 ...

  3. java 保护内存操作的方法

    1.与c++不同,在java中,没有通过使用强制转换指针类型或者通过进行指针运算直接访问内存的方法.在java中使用对象时,需要严格地遵守类型规则.如果存在一个Mountain类对象的引用(类似于c+ ...

  4. tomcat编码配置

    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" ...

  5. 有关getClassLoader().getResourceAsStream(fileName)、class.getResourceAsStream(fileName)和().getContextClassLoader().getResourceAsStream(fileName)的区别

    一:前言 在自己获取属性时,碰见了XX.class.getResourceAsStream(fileName),自己对这个其实不是很理解,上网查了下资料,又看到了上述的几个,所以就研究了下. 二:内容 ...

  6. JAVA 成员访问权限修饰符

    修饰符         类内部     package内         子类         其他 public             允许         允许                 ...

  7. eclipse更改web项目的WebContent目录

    在使用eclipse 中 , 相信大家比我更是轻车熟路了 ( 我平常一般用 Intellij idea 的 ), 下面讲解一下在eclipse web项目中 , 如何设置 webroot 目录指向问题 ...

  8. 12.22笔记(关于CALayer//Attributes//CALayer绘制图层//CALayer代理绘图//CALayer动画属性//CALayer自定义子图层//绘图pdf文件//绘图渐变效果)

    12.22笔记 pdf下载文件:https://www.evernote.com/shard/s227/sh/f81ba498-41aa-443b-81c1-9b569fcc34c5/f033b89a ...

  9. A trick in Exploit Dev

    学习Linux BOF的时候,看了这个文章,https://sploitfun.wordpress.com/2015/06/23/integer-overflow/ ,原文给出的exp无法成功, 此时 ...

  10. cobalt strike使用笔记

    启动: ./teamserver 192.168.74.1 admin #启动cs服务器.admin为密码. 监听器: windows/beacon_dns/reverse_dns_txtwindow ...