P3369 【模板】普通平衡树 Treap
P3369 【模板】普通平衡树(Treap/SBT)
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
插入x数
删除x数(若有多个相同的数,因只删除一个)
查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
查询排名为x的数
求x的前驱(前驱定义为小于x,且最大的数)
- 求x的后继(后继定义为大于x,且最小的数)
输入输出格式
输入格式:
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1 \leq opt \leq 61≤opt≤6 )
输出格式:
对于操作3,4,5,6每行输出一个数,表示对应答案
输入输出样例
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
106465
84185
492737
说明
时空限制:1000ms,128M
1.n的数据范围: n \leq 100000n≤100000
2.每个数的数据范围: [-{10}^7, {10}^7][−107,107]
来源:Tyvj1728 原名:普通平衡树
在此鸣谢
code
treap 真是个好东西。。
#include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std; const int N = ; struct Data{
int l,r,val,key,siz,cnt;
}t[N];
int Root,tn,ans; inline char nc() {
static char buf[],*p1 = buf,*p2 = buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2) ? EOF :*p1++;
}
inline int read() {
int x = ,f = ;char ch=nc();
for (; ch<''||ch>''; ch = nc())
if (ch == '-') f = -;
for (; ch>=''&&ch<=''; ch = nc())
x = x*+ch-'';
return x * f;
} inline void pushup(int x) {
t[x].siz = t[t[x].l].siz + t[t[x].r].siz + t[x].cnt;
}
inline void leftturn(int &k) {
int a = t[k].r;
t[k].r = t[a].l;
t[a].l = k;
t[a].siz = t[k].siz;
pushup(k);
k = a;
}
inline void rightturn(int &k) {
int a = t[k].l;
t[k].l = t[a].r;
t[a].r = k;
t[a].siz = t[k].siz;
pushup(k);
k = a;
}
void Insert(int &k,int x) {
if (k==) {
tn++;k = tn;
t[k].siz = t[k].cnt = ;
t[k].val = x;t[k].key = rand();
return ;
}
t[k].siz++;
if (t[k].val==x) t[k].cnt ++;
else if (x > t[k].val) {
Insert(t[k].r,x);
if (t[t[k].r].key < t[k].key) leftturn(k);
}
else {
Insert(t[k].l,x);
if (t[t[k].l].key < t[k].key) rightturn(k);
}
}
void Delete(int &k,int x) {
if (k==) return ;
if (t[k].val==x) {
if (t[k].cnt > ) {
t[k].cnt--;t[k].siz--;return ;
}
if (t[k].l * t[k].r == ) k = t[k].l + t[k].r;
else if (t[t[k].l].key < t[t[k].r].key) {
rightturn(k);Delete(k,x);
}
else {
leftturn(k);Delete(k,x);
}
}
else if (x > t[k].val) {
t[k].siz--;Delete(t[k].r,x);
}
else {
t[k].siz--;Delete(t[k].l,x);
}
}
int getk(int k,int x) {
if (k==) return ;
if (t[k].val==x) return t[t[k].l].siz + ;
else if (x > t[k].val)
return t[t[k].l].siz + t[k].cnt + getk(t[k].r,x);
else return getk(t[k].l,x);
}
int getkth(int k,int x) {
if (k==) return ;
if (x <= t[t[k].l].siz) return getkth(t[k].l,x);
else if (x > t[t[k].l].siz + t[k].cnt)
return getkth(t[k].r,x-t[t[k].l].siz-t[k].cnt);
else return t[k].val;
}
void getpre(int k,int x) {
if (k==) return ;
if (t[k].val < x) ans = k,getpre(t[k].r,x);
else getpre(t[k].l,x);
}
void getsuc(int k,int x) {
if (k==) return ;
if (t[k].val > x) ans = k,getsuc(t[k].l,x);
else getsuc(t[k].r,x);
} int main() {
int n = read();
while (n--){
int opt = read(),x = read();
if (opt==) Insert(Root,x);
else if (opt==) Delete(Root,x);
else if (opt==) printf("%d\n",getk(Root,x));
else if (opt==) printf("%d\n",getkth(Root,x));
else if (opt==) ans = ,getpre(Root,x),printf("%d\n",t[ans].val);
else ans = ,getsuc(Root,x),printf("%d\n",t[ans].val);
}
return ;
}
更新后的treap
#include<cstdio>
#include<algorithm>
#include<ctime> using namespace std; #define lson t[k].l
#define rson t[k].r
const int N = ; struct Data{
int l,r,val,key,siz,cnt;
}t[N];
int Root,tn,ans; inline char nc() {
static char buf[],*p1 = buf,*p2 = buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2) ? EOF :*p1++;
}
inline int read() {
int x = ,f = ;char ch=nc();
for (; ch<''||ch>''; ch = nc())
if (ch == '-') f = -;
for (; ch>=''&&ch<=''; ch = nc())
x = x*+ch-'';
return x * f;
} inline void pushup(int k) {
t[k].siz = t[lson].siz + t[rson].siz + t[k].cnt;
}
inline void leftturn(int &k) {
int a = rson;
rson = t[a].l;
t[a].l = k;
t[a].siz = t[k].siz;
pushup(k);
k = a;
}
inline void rightturn(int &k) {
int a = lson;
lson = t[a].r;
t[a].r = k;
t[a].siz = t[k].siz;
pushup(k);
k = a;
}
void Insert(int &k,int x) {
if (k==) {
tn++;k = tn;
t[k].siz = t[k].cnt = ;
t[k].val = x;t[k].key = rand();
return ;
}
t[k].siz++;
if (t[k].val==x) t[k].cnt ++;
else if (x > t[k].val) {
Insert(rson,x);
if (t[rson].key < t[k].key) leftturn(k);
}
else {
Insert(lson,x);
if (t[lson].key < t[k].key) rightturn(k);
}
}
void Delete(int &k,int x) {
if (k==) return ;
if (t[k].val==x) {
if (t[k].cnt > ) {
t[k].cnt--;t[k].siz--;return ;
}
if (lson * rson == ) k = lson + rson;
else if (t[lson].key < t[rson].key) {
rightturn(k);Delete(k,x);
}
else {
leftturn(k);Delete(k,x);
}
}
else if (x > t[k].val) {
t[k].siz--;Delete(rson,x);
}
else {
t[k].siz--;Delete(lson,x);
}
}
int getk(int k,int x) {
if (k==) return ;
if (t[k].val==x) return t[lson].siz + ;
else if (x > t[k].val)
return t[lson].siz + t[k].cnt + getk(rson,x);
else return getk(lson,x);
}
int getkth(int k,int x) {
if (k==) return ;
if (x <= t[lson].siz) return getkth(lson,x);
else if (x > t[lson].siz + t[k].cnt)
return getkth(rson,x-t[lson].siz-t[k].cnt);
else return t[k].val;
}
void getpre(int k,int x) {
if (k==) return ;
if (t[k].val < x) ans = k,getpre(rson,x);
else getpre(lson,x);
}
void getsuc(int k,int x) {
if (k==) return ;
if (t[k].val > x) ans = k,getsuc(lson,x);
else getsuc(rson,x);
} int main() {
int n = read();
while (n--){
int opt = read(),x = read();
if (opt==) Insert(Root,x);
else if (opt==) Delete(Root,x);
else if (opt==) printf("%d\n",getk(Root,x));
else if (opt==) printf("%d\n",getkth(Root,x));
else if (opt==) ans = ,getpre(Root,x),printf("%d\n",t[ans].val);
else ans = ,getsuc(Root,x),printf("%d\n",t[ans].val);
}
return ;
}
P3369 【模板】普通平衡树 Treap的更多相关文章
- luoguP3369[模板]普通平衡树(Treap/SBT) 题解
链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...
- 【模板】平衡树——Treap和Splay
二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...
- 算法模板——平衡树Treap 2
实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...
- 普通平衡树Treap(含旋转)学习笔记
浅谈普通平衡树Treap 平衡树,Treap=Tree+heap这是一个很形象的东西 我们要维护一棵树,它满足堆的性质和二叉查找树的性质(BST),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...
- 2021.12.06 平衡树——Treap
2021.12.06 平衡树--Treap https://www.luogu.com.cn/blog/HOJQVFNA/qian-xi-treap-ping-heng-shu 1.二叉搜索树 1.1 ...
- hiho #1325 : 平衡树·Treap
#1325 : 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? ...
- hiho一下103周 平衡树·Treap
平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二 ...
- 【山东省选2008】郁闷的小J 平衡树Treap
小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架.虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他面临着被解雇的危险,这也正是他所郁闷的.具体说来,书架由N ...
- Hihocoder 1325 平衡树·Treap(平衡树,Treap)
Hihocoder 1325 平衡树·Treap(平衡树,Treap) Description 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二叉 ...
- HihoCoder 1325 平衡树·Treap
HihoCoder 1325 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说 ...
随机推荐
- BroadCast广播机制应用与实例
如何编写广播接收器 第一步:需要继承BroadcastReceiver类,覆写其中的onReceive()方法. class MyBroadcastReceiver extends Broadcast ...
- js的加密和解密
最近在研究js的加密和解密的问题,上网上搜出来很多方法,不过不知道到底哪一个会比较管用.这里是今天找到的一些关于base64加密解密的js代码,已经经过试验,可以使用,不过网上很多加密解密的工具,这种 ...
- css 居中问题总结
html代码: <div class="box"> <div class="box-item"> 文字 </div> < ...
- Ubuntu 修改host并重启网络
Ubuntu系统的Hosts只需修改/etc/hosts文件,在目录中还有一个hosts.conf文件,刚开始还以为只需要修改这个就可以了,结果发现是需要修改hosts.修改完之后要重启网络.具体过程 ...
- Burpsuite Professional安装及使用教程
转自:https://www.jianshu.com/p/edbd68d7c341 1.先从吾爱破解论坛下载工具:https://down.52pojie.cn/Tools/Network_Analy ...
- python3操作excel01(对excel的基础操作)
#!/usr/bin/env python# -*- coding:UTF-8 -*- import requestsfrom bs4 import BeautifulSoupfrom bs4 imp ...
- asterisk-java ami2 事件监听
asteriskServer文章1提到啦怎么获取,就不解释 asteriskServer.addChainListener(new AsteriskeventListenerInit());//整个服 ...
- BandwagonHost 5个数据中心/机房Ping速度测试亲自体验
我们选择Bandwagonhost服务器的原因之一在于有5个数据中心,而且与众多其他VPS不同之处在于可以自己后台切换机房和IP,这样我们 在遇到不满意的速度时候,可以自己切换其他机房更换,而且对于有 ...
- 全站变灰的CSS代码-适合特殊时刻哀悼
将下面CSS代码应用到HTML标签或者是BODY标签 filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.o ...
- PhoneGap+JQuery Mobile移动应用开发学习笔记
最近一直在学习使用PhoneGap+JQuery Mobile的开发框架开发Android应用,抛开这个框架的运行效率不说,暂且将使用中遇到的问题进行一下整理. 1.JS文件引用顺序 也许在进行web ...