treap板子(洛谷 P3369 【模板】普通平衡树(Treap/SBT))
由于有相同的数,每个节点加一个权值表示此数出现的次数
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
#define MAXI 2147483647
//http://blog.csdn.net/h348592532/article/details/52837228随机数
int rand1()
{
static int x=;
return x=(48271LL*x+)%;
}
struct Node
{
Node* ch[];
int r;//优先级
int v;//value
int size;//维护子树的节点个数
int num;//当前数字出现次数
int cmp(int x) const//要在当前节点的哪个子树去查找,0左1右
{
if(x==v) return -;
return v<x;//x<v?0:1
}
void upd()
{
size=num;
if(ch[]!=NULL) size+=ch[]->size;
if(ch[]!=NULL) size+=ch[]->size;
}
}nodes[];
int mem,n;
Node* root=NULL;
void rotate(Node* &o,int d)
{
Node* t=o->ch[d^];o->ch[d^]=t->ch[d];t->ch[d]=o;
o->upd();t->upd();//o是t子节点,一定要这个顺序upd
o=t;//将当前节点变成旋转完后新的父节点
}
Node* getnode()
{
return &nodes[mem++];
}
void insert(Node* &o,int x)
{
if(o==NULL)
{
o=getnode();o->ch[]=o->ch[]=NULL;
o->v=x;o->r=rand1();o->num=;
}
else
{
if(o->v==x) ++(o->num);
else
{
int d=o->v < x;//x < o->v?0:1
insert(o->ch[d],x);
if(o->r < o->ch[d]->r) rotate(o,d^);//不是 x < o->ch[d]->r
}
}
o->upd();
}
void remove(Node* &o,int x)
{
int d=o->cmp(x);
if(d==-)
{
if(o->num > )
{
--(o->num);
}
if(o->num == )
{
if(o->ch[]==NULL) o=o->ch[];
else if(o->ch[]==NULL) o=o->ch[];
else
{
//int d2= o->ch[0]->r > o->ch[1]->r;//o->ch[0]->r > o->ch[1]->r ? 1:0
int d2=o->ch[]->r < o->ch[]->r;//o->ch[1]->r <= o->ch[0]->r
rotate(o,d2);
remove(o->ch[d2],x);
//左旋则原节点变为新节点的左子节点,右旋相反
}
}
}
else remove(o->ch[d],x);
if(o!=NULL) o->upd();
}
bool find(Node* o,int x)
{
int d;
while(o!=NULL)
{
d=o->cmp(x);
if(d==-) return ;
else o=o->ch[d];
}
return ;
}
int kth(Node* o,int k)
{
if(o==NULL||k<=||k > o->size) return ;
int s= o->ch[]==NULL ? : o->ch[]->size;
if(k>s&&k<=s+ o->num) return o->v;
else if(k<=s) return kth(o->ch[],k);
else return kth(o->ch[],k-s- o->num);
}
int rk(Node* o,int x)
{
int r=o->ch[]==NULL ? : o->ch[]->size;
if(x==o->v) return r+;
else if(x<o->v) return rk(o->ch[],x);
else return r+ o->num +rk(o->ch[],x);
}
int pre(Node* o,int x)
{
if(o==NULL) return -MAXI;
int d=o->cmp(x);
if(d<=) return pre(o->ch[],x);
else return max(o->v,pre(o->ch[],x));
}
int nxt(Node* o,int x)
{
if(o==NULL) return MAXI;
int d=o->cmp(x);
if(d!=) return nxt(o->ch[],x);
else return min(o->v,nxt(o->ch[],x));
}
int main()
{
int i,o,x;
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("%d%d",&o,&x);
if(o==) insert(root,x);
else if(o==) remove(root,x);
else if(o==) printf("%d\n",rk(root,x));
else if(o==) printf("%d\n",kth(root,x));
else if(o==) printf("%d\n",pre(root,x));
else printf("%d\n",nxt(root,x));
}
return ;
}
本来想写成相同的数分成多个节点放的,写了一会儿各种细节,炸了
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
struct Node
{
Node* ch[];
int r;//优先级
int v;//value
int size;//维护子树的节点个数 int cmp(int x) const//要在当前节点的哪个子树去查找,0左1右
{
if(x==v) return -;
return v<x;//x<v?0:1
}
void upd()
{
size=;
if(ch[]!=NULL) size+=ch[]->size;
if(ch[]!=NULL) size+=ch[]->size;
}
}nodes[];
int mem;
void rotate(Node* &o,int d)
{
Node* t=o->ch[d^];o->ch[d^]=t->ch[d];t->ch[d]=o;
o->upd();t->upd();
o=t;//将当前节点变成旋转完后新的父节点
}
Node* getnode()
{
return &nodes[mem++];
}
void insert(Node* &o,int x)
{
if(o==NULL)
{
o=getnode();o->ch[]=o->ch[]=NULL;
o->v=x;o->r=rand();
}
else
{
//int d=o->cmp(x);不重复
int d=o->v <= x;//x < o->v?0:1
//按照以上左侧的插入方式,相等的会在左子树中插入
insert(o->ch[d],x);
if(o->ch[d]->r > o->r)//不是> x
rotate(o,d^);
}
o->upd();
}
void remove(Node* &o,int x)
{
int d=o->cmp(x);
if(d==-)
{
if(o->ch[]==NULL) o=o->ch[];
else if(o->ch[]==NULL) o=o->ch[];
else
{
//int d2= o->ch[0]->r > o->ch[1]->r;//o->ch[0]->r > o->ch[1]->r ? 1:0
int d2=o->ch[]->r <= o->ch[]->r;
rotate(o,d2);
remove(o->ch[d2],x);
//左旋则原节点变为新节点的左子节点,右旋相反
}
}
else remove(o->ch[d],x);
if(o!=NULL) o->upd();
}
bool find(Node* o,int x)
{
int d;
while(o!=NULL)
{
d=o->cmp(x);
if(d==-) return ;
else o=o->ch[d];
}
return ;
}
int kth(Node* o,int k)
{
if(o==NULL||k<=||k > o->size) return ;
int s= o->ch[]==NULL ? : o->ch[]->size;
if(k==s+) return o->v;
else if(k<=s) return kth(o->ch[],k);
else return kth(o->ch[],k-s-);
}
//int rank(Node* o,int x)//不可重复
//{
// int r= t->ch[0]==NULL ? 0 : t->ch[0]->size;
// if(x==o->v) return r+1;
// else if(x<o->v) return rank(o->ch[0],x);
// else return r+1+rank(o->ch[1],x);
//}
int rank(Node* o,int x)//支持重复
{
int r=t->ch[]==NULL ? : t->ch[]->size;
if(x==o->v)
{
int t=rank(o->ch[
}
}
int pre(Node* o,int x)
{
if(o==NULL) return -;
if(x==o->v) return
if(x<o->v) return min(o->v,pre(o->ch[],
}
int main()
{
srand(time()); return ;
}
treap板子(洛谷 P3369 【模板】普通平衡树(Treap/SBT))的更多相关文章
- 洛谷.3369.[模板]普通平衡树(fhq Treap)
题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...
- 【洛谷P3369】普通平衡树——Splay学习笔记(一)
二叉搜索树(二叉排序树) 概念:一棵树,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉搜索树 ...
- 洛谷.3369.[模板]普通平衡树(Splay)
题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...
- 洛谷.3391.[模板]文艺平衡树(Splay)
题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...
- 洛谷P3369 【模板】普通平衡树(Treap/SBT)
洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...
- 【洛谷P3369】【模板】普通平衡树题解
[洛谷P3369][模板]普通平衡树题解 题目链接 题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3 ...
- 洛谷P3369普通平衡树(Treap)
题目传送门 转载自https://www.cnblogs.com/fengzhiyuan/articles/7994428.html,转载请注明出处 Treap 简介 Treap 是一种二叉查找树.它 ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- luoguP3369[模板]普通平衡树(Treap/SBT) 题解
链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...
- (treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...
随机推荐
- IOS开发 AFN和ASI
做项目有一段时间了,项目过程中处理网络请求难免的,而对于选择第三方来处理网络请求肯定是个明智的选择! AFNetworking和ASIHTTPRequest 这两个第三方该如何选择 我 ...
- 【Todo】C++和Java里面的浮点数及各种数字表示
今天看了这篇文章,是讲C++中的浮点类型的:<浮点数的二进制表示> 再复习一下Java里面的Float和Double. 首先,直接数字赋值给Float变量是不行的,数字后要加上F,这样写: ...
- 从日志文件解决ArcGIS Server性能低下问题的步骤(1)
日志级别和结构 http://www.cnblogs.com/fortoday/archive/2011/03/30/2000348.html ArcGIS Server日志文件分为几个记录级别: 无 ...
- zookeeper的集群部署
1.上传安装包到集群服务器 2.解压 3.修改配置文件 进入zookeeper的安装目录的conf目录 cp zoo_sample.cfg zoo.cfg vi zoo.cfg # The numbe ...
- [Bash] Move and Copy Files and Folders with Bash
In this lesson we’ll learn how to move and rename files (mv) and copy (cp) them. Move index.html to ...
- jason数据格式 -- 扫盲
JSON是 JavaScript Object Notation的简称,是一种轻量的数据表示方法.jason格式採用key:value的方式记录数据,非常直观,比XML简洁,因而大受欢迎 介绍jaso ...
- 什么是cookie?session和cookie的区别?
1.cookie数据存放在客户的浏览器上,session数据放在服务器上. 2.cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗 考虑到安全应当使用session ...
- windows下的java+maven项目环境搭建
年底了,进公司刚好半年,于是全新一轮的挑战开始:让我接触java项目了,真的是全新的,完全一片茫然.经过了半个月的折腾,把环境搭了一遍又一遍,还可以小小的改一下程序,还OK啦~继续努力.接下来,进入正 ...
- java 编码设置
- YTU 2894: G--我要去内蒙古大草原
2894: G--我要去内蒙古大草原 时间限制: 1 Sec 内存限制: 128 MB 提交: 162 解决: 8 题目描述 春天到了,小明想要从烟台开车去内蒙古大草原放松一下,这两地的距离是14 ...