[luogu P3369]【模板】普通平衡树(Treap/SBT)
[luogu 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 原名:普通平衡树
在此鸣谢
用一下午的时间打了一发treap(第一次打),感觉还挺好,实现起来没有其他平衡树高。。
然后。。主要是操作方便,旋转容易(主要依赖于树堆性质和随机期望)。。
不说了,直接贴板子。。
code:
再来一发链表指针版的(据说写大数据结构链表很常用)——
code:
%:pragma GCC optimize() #include<bits/stdc++.h> using namespace std; int ans; class tnode{ private: ]; public: tnode() {ch[]=ch[]=;} inline void newnode(tnode* &cur,int x) { cur=]=cur->ch[]=,cur->v=x,cur->s=cur->c=,cur->k=rand(); } inline void update(tnode* cur) { cur->s=cur->c; ]!=) cur->s+=cur->ch[]->s; ]!=) cur->s+=cur->ch[]->s; } inline void rotate(tnode* &cur,int dir) { tnode *tmp=cur->ch[dir^]->ch[dir]; ]->ch[dir]==) cur->ch[dir^]->ch[dir]=new tnode; cur->ch[dir^]->ch[dir]=cur; cur=cur->ch[dir^]; cur->ch[dir]->ch[dir^]=tmp; update(cur->ch[dir]); update(cur); } inline void insert(tnode* &cur,int x) { if (cur==NULL) {newnode(cur,x); return;} if (cur->v==x) {cur->c++; cur->s++; return;} bool p=cur->v<x; insert(cur->ch[p],x); ); else update(cur); } inline void remove(tnode* &cur,int x) { if (!cur) return; if (cur->v==x) { ) {cur->c--; cur->s--; return;} ]&&!cur->ch[]) {cur=; return;} ]||!cur->ch[]) { cur=cur->ch[]?cur->ch[]:cur->ch[]; return; } ]->k<cur->ch[]->k; rotate(cur,p); remove(cur->ch[p],x); update(cur); return; } bool p=cur->v<x; remove(cur->ch[p],x); update(cur); } inline int x_rank(tnode* cur,int x) { ; ; ]!=) s=cur->ch[]->s; ; ],x); ],x); } inline int rank_x(tnode* cur,int x) { ; ; ]!=) s=cur->ch[]->s; &&x<=s+cur->c) return cur->v; ) ],x); ],x-s-cur->c); } inline void x_pre(tnode* cur,int x) { if (!cur) return; ],x); ],x); } inline void x_suc(tnode* cur,int x) { if (!cur) return; ],x); ],x); } }t,*root; inline int read() { ,f=; char ch=getchar(); :,ch=getchar(); +ch-',ch=getchar(); return x*f; } int main() { srand(); for (int Q=read(),o,x; Q; --Q) { o=read(),x=read(); switch (o) { : t.insert(root,x); break; : t.remove(root,x); break; : printf("%d\n",t.x_rank(root,x)); break; : printf("%d\n",t.rank_x(root,x)); break; : t.x_pre(root,x); printf("%d\n",ans); break; : t.x_suc(root,x); printf("%d\n",ans); break; } } ; }
upd 2017/11/18:
学了一下splay,写了一下,神tm好难写啊。。。
题解过段时间补吧。
code:
#pragma GCC optimize(2) #include <cstdio> namespace OJ{ void Online_Judge() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif } } using namespace OJ; namespace fastIO { #define gec(c) getchar(c) #define puc(c) putchar(c) char ch; inline int read() { ,f=; ch=gec(); ') { if (ch=='-') f=-f; ch=gec(); } ') { x=(x<<)+(x<<)+ch-'; ch=gec(); } return x*f; } ]; template <class T> inline void write(T x) { ) { puc('); return; } ) { x=-x,puc('-'); } ; x; x/=) w[++cnt]=x%; ); } inline void newline() { puc('\n'); } } using namespace fastIO; #define Splay node class Splay { private: int s,t,v; node* c[]; public: node () { s=t=; c[]=c[]=c[]=; } node* newnode (int v) ; bool dir (node* x) ; void upd (node* x) ; void rot (node* x) ; void splay (node* x,node* a) ; void find (int v) ; void insert (node* &x,int v) ; void erase (int v) ; int rank (int v) ; int kth (node* x,int v) ; int pre (int v) ; int suc (int v) ; } t,*r,*ori,*g; node* Splay::newnode (int v) { node* ret=new node(); ret->v=v; return ret; } bool Splay::dir (node* x) { ]->c[]) ; ]->c[]==x; } void Splay::upd (node* x) { x->s=x->t; ]) x->s+=x->c[]->s; ]) x->s+=x->c[]->s; } void Splay::rot (node* x) { ]; ]) y->c[]->c[dir(y)]=x; x->c[]=y->c[]; y->c[p]=x->c[p^]; ]) x->c[p^]->c[]=y; x->c[p^]=y; y->c[]=x; upd(y),upd(x); } void Splay::splay (node* x,node* o) { ]==o) return; ]!=o; ) { ]->c[]==o) { rot(x); if (!o) r=x; return; } ])) rot(x),rot(x); ]),rot(x); } if (!o) r=x; } void Splay::find (int v) { for (g=r; g->v!=v; g=g->c[v>g->v]) ; splay(g,); } void Splay::insert (node* &x,int v) { if (!x) { x=g=newnode(v); return; } if (v==x->v) { ++x->s,++x->t,g=x; return; } insert(x->c[v>x->v],v); x->c[v>x->v]->c[]=x; upd(x); } void Splay::erase (int v) { find(v); ) { --r->s,--r->t; return; } ]||!r->c[]) { ]) r=r->c[],r->c[]=; else ]) r=r->c[],r->c[]=; ; return; } ]; g->c[]; g=g->c[]) ; splay(g,r); g->c[]=,g->c[]=r->c[]; ]) g->c[]->c[]=g; r=g,upd(r); } int Splay::pre (int v) { insert(r,v); splay(g,); ]; g->c[]; g=g->c[]) ; int ret=g->v; erase(v); return ret; } int Splay::suc (int v) { insert(r,v); splay(g,); ]; g->c[]; g=g->c[]) ; int ret=g->v; erase(v); return ret; } int Splay::rank (int v) { find(v); splay(g,); ]?r->c[]->s:; ; } int Splay::kth (node* x,int v) { ; ]?:x->c[]->s; if (v>s&&v<=s+x->t) return x->v; else ],v); ],v-s-x->t); } int Q; int main() { Online_Judge(); r=,Q=read(); ; q<=Q; ++q) { int o=read(),x=read(); switch (o) { : t.insert(r,x),t.splay(g,); break; : t.erase(x); break; : write(t.rank(x)),newline(); break; : write(t.kth(r,x)),newline(); break; : write(t.pre(x)),newline(); break; : write(t.suc(x)),newline(); break; } } ; }
[luogu P3369]【模板】普通平衡树(Treap/SBT)的更多相关文章
- luoguP3369[模板]普通平衡树(Treap/SBT) 题解
链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...
- 【模板】平衡树——Treap和Splay
二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...
- 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline _ ...
- 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...
- 红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 近几天闲来无事...就把各种平衡树都写了一下... 下面是红黑树(Red Black Tree) 喜闻乐见拿到了luo ...
- 洛谷P3369 【模板】普通平衡树(Treap/SBT)
洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...
- AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369
[模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...
- P3369 【模板】普通平衡树 Treap
P3369 [模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询 ...
- 算法模板——平衡树Treap 2
实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...
随机推荐
- python基础(14)-反射&类的内置函数
反射 几个反射相关的函数可参考python基础(10)-匿名函数&内置函数中2.2.4反射相关 类的一些内置函数 __str__()&__repr__() 重写__str__()函数类 ...
- webstorm 配置 开发微信小程序
默认情况下,webstorm是不支持wxml和wxss的文件类型,不会有语法高亮 设置高亮 除了高亮,还需要代码提示, 所幸已经有前辈整理了小程序的代码片段,只需要导入其安装包即可使用,包文件路径如下 ...
- jsp一些使用技巧
1.web.xml中配置error页面 一.<error-page> <error-code>500</error-code> <location>50 ...
- iPhone IOS10安装APP没提示连接网络(无法联网)的解决办法
iPhone升级ios10之后,遇到如标题所述问题时: 1.退出APP,设置-蜂窝移动网络-无线局域网助理-开启 2.进入APP,这时候就回提示连接网络了. 提醒: 数据流量有限的朋友,平时请关闭&q ...
- Python基础(二)自定义函数
1.判断字符串,内容是否为数字 我们用python:xlrd读Excel内容时,本来只是输入的整数字,经常读出来的是float类型 我们需要自动转成整型,意思就是说,读出来的和我们输入的一样,但是,我 ...
- OAuth2认证和授权入门
OAuth2四种授权方式 四种授权方式 OAuth 2.0定义了四种授权方式. 密码模式(resource owner password credentials) 授权码模式(authorizatio ...
- nodejs之querystring(查询字符串)
querystring模块经常用在URL参数的处理,一共有四个方法: 1. stringify (字符串转对象) 2. parse (对象转字符串) 3. escape (对字符串进行URL编码) 4 ...
- 第七节 DOM操作应用-高级
表格应用: 获取:tBodies.tHead.tFoot.rows.cells <!DOCTYPE html> <html lang="en"> <h ...
- HTML5中 audio标签的样式修改
由于html5的流行,现在移动端大多数的需求都可以使用audio来播放音频,但您可能只是需要很简单的播放/停止效果,但不同的浏览器上的audio样式却不尽人意,那么要怎么改变这个样式呢,其实它的原理比 ...
- 51Nod 1058 N的阶乘的长度
输入N求N的阶乘的10进制表示的长度.例如6! = 720,长度为3. Input 输入N(1 <= N <= 10^6) Output 输出N的阶乘的长度 Input示例 6 Out ...