这是一个treap裸题,还可以用splay,替罪羊树,线段树等等写

treap是树和堆结合,可以方便的在O(log(n))期望时间内进行以下操作,因此treap又叫做名次树

  1. 插入x数

  2. 删除x数(若有多个相同的数,因只删除一个)

  3. 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)

  4. 查询排名为x的数

  5. 求x的前驱(前驱定义为小于x,且最大的数)

  6. 求x的后继(后继定义为大于x,且最小的数)
#include<bits/stdc++.h>
#include<ext/rope>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1 using namespace std;
using namespace __gnu_cxx; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f; struct Node{
Node* ch[];
int r;//排名
int v;//权值
int s;//节点数
int flag;
Node()
{
ch[]=ch[]=NULL;
r=rand();v=;
s=flag=;
}
};
Node *root;
void maintain(Node* &o)//更新当前结点子树的节点数
{
o->s=o->flag;
if(o->ch[]!=NULL)o->s+=o->ch[]->s;//左子树不为空就加上数量
if(o->ch[]!=NULL)o->s+=o->ch[]->s;//右子树不为空就加上数量
}
void Rotate(Node* &o,int d)//d=0左旋,d=1右旋
{
Node* k=o->ch[d^];
o->ch[d^]=k->ch[d];
k->ch[d]=o;
maintain(o);maintain(k);
o=k;
}
void Insert(Node* &o,int d)
{
if(o==NULL)//子树为空直接加上去
{
o=new Node;
o->v=d;
return ;
}
else if(o->v==d)//可能会相等
{
o->flag++;
maintain(o);
return ;
}
int d1=d>o->v ? :;//判断搜索哪一颗子树
Insert(o->ch[d1],d);
if(o->ch[d1]->r > o->r)Rotate(o,d1^);
else maintain(o);
}
void Remove(Node* &o,int d)
{
if(o==NULL)return ;
if(o->v==d)
{
if(o->flag>)o->flag--;//该节点有多个数
else
{
if(o->ch[]==NULL&&o->ch[]==NULL)o=NULL;
else if(o->ch[]!=NULL&&o->ch[]!=NULL)
{
if(o->ch[]->r > o->ch[]->r)Rotate(o,),Remove(o->ch[],d);
else Rotate(o,),Remove(o->ch[],d);
}
else //有一个节点不为空,就拿另一个补上
{
if(o->ch[]==NULL)o=o->ch[];
else o=o->ch[];
}
}
if(o!=NULL)maintain(o);
}
else //根据d的大小找左右子树
{
if(d < o->v)Remove(o->ch[],d);
else if(d > o->v)Remove(o->ch[],d);
if(o!=NULL)maintain(o);
}
}
int kth(Node* o,int k)//查询排名为k的节点
{
if(k<||k > o->s||o==NULL)return ;//不合法的情况
int ss=;//左子树的节点
if(o->ch[]!=NULL)ss=o->ch[]->s;
if(k>=ss+&&k<=o->flag+ss)return o->v;
if(ss>=k)return kth(o->ch[],k);//左边够大了,从左边找
else return kth(o->ch[],k-ss-o->flag);
}
int Rank(Node* o,int k)//查询k的排名
{
if(o==NULL)return ;
int ss=;
if(o->ch[]!=NULL)ss=o->ch[]->s;
if(o->v==k)return ss+;
if(o->v > k)return Rank(o->ch[],k);//向左搜
else return ss+o->flag+Rank(o->ch[],k);//加上左子树的节点
}
void qq(Node* o,int k,int &ans)
{
if(o==NULL)return ;
if(o->v < k)
{
ans=max(ans,o->v);
if(o->ch[]!=NULL)qq(o->ch[],k,ans);
}
else
{
if(o->ch[]!=NULL)qq(o->ch[],k,ans);
}
}
void hj(Node* o,int k,int &ans)
{
if(o==NULL)return ;
if(o->v > k)
{
ans=min(ans,o->v);
if(o->ch[]!=NULL)hj(o->ch[],k,ans);
}
else
{
if(o->ch[]!=NULL)hj(o->ch[],k,ans);
}
}
int main()
{
srand(time(NULL));
int n;
cin>>n;
while(n--)
{
int a,b;
cin>>a>>b;
if(a==)Insert(root,b);
else if(a==)Remove(root,b);
else if(a==)printf("%d\n",Rank(root,b));
else if(a==)printf("%d\n",kth(root,b));
else if(a==)
{
int ans=;qq(root,b,ans);
printf("%d\n",ans);
}
else
{
int ans=1e9;hj(root,b,ans);
printf("%d\n",ans);
}
}
return ;
}
/******************* ********************/

洛谷p3369 treap的更多相关文章

  1. 洛谷P3369 【模板】普通平衡树(Treap/SBT)

    洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...

  2. 【洛谷P3369】【模板】普通平衡树题解

    [洛谷P3369][模板]普通平衡树题解 题目链接 题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3 ...

  3. 洛谷P3369普通平衡树(Treap)

    题目传送门 转载自https://www.cnblogs.com/fengzhiyuan/articles/7994428.html,转载请注明出处 Treap 简介 Treap 是一种二叉查找树.它 ...

  4. 在洛谷3369 Treap模板题 中发现的Splay详解

    本题的Splay写法(无指针Splay超详细) 前言 首先来讲...终于调出来了55555...调了整整3天..... 看到大部分大佬都是用指针来实现的Splay.小的只是按照Splay的核心思想和原 ...

  5. 绝对是全网最好的Splay 入门详解——洛谷P3369&BZOJ3224: Tyvj 1728 普通平衡树 包教包会

    平衡树是什么东西想必我就不用说太多了吧. 百度百科: 一个月之前的某天晚上,yuli巨佬为我们初步讲解了Splay,当时接触到了平衡树里的旋转等各种骚操作,感觉非常厉害.而第二天我调Splay的模板竟 ...

  6. 洛谷 P3369 【模板】普通平衡树 (Treap)

    题目链接:P3369 [模板]普通平衡树 题意 构造一种数据结构满足给出的 6 种操作. 思路 平衡树 平衡树的模板题. 先学习了一下 Treap. Treap 在插入结点时给该结点随机生成一个额外的 ...

  7. AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369

    [模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...

  8. 洛谷P3369 【模板】普通平衡树(FHQ Treap)

    题面 传送门 题解 写了一下\(FHQ\ Treap\) //minamoto #include<bits/stdc++.h> #define R register #define inl ...

  9. [洛谷P3369] 普通平衡树 Treap & Splay

    这个就是存一下板子...... 题目传送门 Treap的实现应该是比较正经的. 插入删除前驱后继排名什么的都是平衡树的基本操作. #include<cstdio> #include< ...

随机推荐

  1. C++编译错误C2365

    曾经我们说重定义一般是函数或者变量的重定义.今天遇到了一个新类型的重定义errorC2365 #include <iostream> using namespace std; class ...

  2. (2) yum源配置-163

    1.获取yum源文件 登录http://mirrors.163.com/.help/centos.html,查看CentOS6的链接地址(右键点击“CentOS6”,选择复制链接地址),链接地址为:h ...

  3. linux 进程线程

    linux下进程的最大线程数.进程最大数.进程打开的文件数   ===========最大线程数============== linux 系统中单个进程的最大线程数有其最大的限制 PTHREAD_TH ...

  4. ObjC消息机制

    深入浅出ObjC之消息    罗朝辉(http://blog.csdn.net/kesalin) 在入门级别的ObjC 教程中,我们常对从C++或Java 或其他面向对象语言转过来的程序员说,ObjC ...

  5. flex弹性盒模型

    flex 意思是弹性布局,用来给盒模型提供最大的灵活度,指定容器中的项目为弹性布局,类似于float:left; 比float的好处是容器没有设置高度,会根据项目来自适应高度,我们都知道,设置floa ...

  6. java代码连接本地redis数据库

    关于redis的介绍在这里就不说了.今天主要讲解,如何连接redis.连接之前.必须要做的几点: 一.安装redis.下载服务和客户端,然后 二.启动redis服务. 经过这两步的测通以后.我们只需要 ...

  7. KVM和QEMU的关系(转载)

    From:http://blog.sina.com.cn/s/blog_605f5b4f0102uyjv.html KVM是一种基于CPU硬件辅助的全虚拟化技术,没有CPU硬件虚拟化的支持,KVM无法 ...

  8. 线程池 http请求

    package com.aibi.cmdc.test; import java.io.BufferedReader; import java.io.InputStream; import java.i ...

  9. ubuntu 16.04.3 安装完成后的一些初始化工作

    虚拟机安装前记得把桥接调好! 1. 重置root密码 sudo passwd, 然后系统会让你输入密码,这时输入的密码就是root用户的密码,su root切用户 2. 设置固定IP,有重启服务功能令 ...

  10. [ArcGIS]Oracle RAC下创建地理数据库(Create Enterprise Geodatabase)失败的解决方法

    转载请注明原文地址:http://www.cnblogs.com/litou/p/8028843.html 环境:Oracle 11g 11.2.0.1.0(双节点RAC群集),ArcGIS Desk ...