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数的排名(若有多个相同的数 ...
随机推荐
- Samba简单配置--匿名用户共享资料可读可写的实现
http://e-mailwu.blog.163.com/blog/static/65104036200931893921923/ http://www.cnblogs.com/god_like_do ...
- Hashmap在JDK8中的提升
HashMap使用key的hashCode()和equals()方法来将值划分到不同的桶里. 桶的数量通常要比map中的记录的数量要稍大.这样 每一个桶包含的值会比較少(最好是一个).当通过key进行 ...
- 优化 html 标签 为何能用HTML/CSS解决的问题就不要使用JS?
优化 html 标签 2018年05月11日 08:56:24 阅读数:19 有些人写页面会走向一个极端,几乎页面所有的标签都用div,究其原因,用div有很多好处,一个是div没有默认样式,不会有m ...
- 配置pydot环境
第一次配置pydot环境,过程还是比較曲折,看来对这样的模式还不是非常熟悉.断断续续弄了两天弄好了.都是些小要求,小细节问题. 安装的顺序也非常重要: 1.安装python-2.7.8.amd64.m ...
- icvSetWeightsAndClasses
/* *icvSetWeightsAndClasses *作用:给训练样本的权重和类别赋值 */ static void icvSetWeightsAndClasses( CvHaarTraining ...
- hdu1507——Uncle Tom's Inherited Land*
Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- 排队理论之性能分析 - Little Law & Utilization Law
了解一个系统的性能一般是參考一些度量值(Metric),而怎样计算出这些Metric就是我们要讨论的.Little Law(排队理论:利特儿法则)和Utilization Law是Performanc ...
- css hack原理
近期看了几篇关于css hack的文章,认为不错整理一下. css hack非常多人不理解它的原理,事实上大家都知道对于不同的浏览器,CSS的解析程度不一样.因此会导致生成的页面效果不一样:特别是对于 ...
- Activity动态添加Fragment时遇到的问题
1.Activity动态调用代码 TitleFragement a = new TitleFragement(); getFragmentManager().beginTransacti ...
- 关于wireshark
1 对https进行抓包,或者说抓包经过了ssl加密的包 只要有rsa private key就可以了. https://wiki.wireshark.org/SSL 2 对浏览器访问的https的网 ...