[luogu P3369]【模板】普通平衡树(Treap/SBT)

题目描述

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

  1. 插入x数

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

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

  4. 查询排名为x的数

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

  6. 求x的后继(后继定义为大于x,且最小的数)

输入输出格式

输入格式:

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1 \leq opt \leq 61≤opt≤6 )

输出格式:

对于操作3,4,5,6每行输出一个数,表示对应答案

输入输出样例

输入样例#1: 复制

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
输出样例#1: 复制

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)的更多相关文章

  1. luoguP3369[模板]普通平衡树(Treap/SBT) 题解

    链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...

  2. 【模板】平衡树——Treap和Splay

    二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...

  3. 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline _ ...

  4. 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...

  5. 红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 近几天闲来无事...就把各种平衡树都写了一下... 下面是红黑树(Red Black Tree) 喜闻乐见拿到了luo ...

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

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

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

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

  8. P3369 【模板】普通平衡树 Treap

    P3369 [模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询 ...

  9. 算法模板——平衡树Treap 2

    实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...

随机推荐

  1. 运行pytorch代码遇到的error解决办法

    1.no CUDA-capable device is detected 首先考虑的是cuda的驱动问题,查看gpu显示是否正常,然后更新最新的cuda驱动: 第二个考虑的是cuda设备的默认参数是否 ...

  2. 组件式开发(Vue)

    什么是组件式开发: 组件式开发就是将单个组件组合起来,形成一个大的组件进行页面的开发完成 什么是复合型组件: 复合型组件就是将相同的功能写成一个公用的组件(单元组件),供其他组件使用,就类似于后台开发 ...

  3. mysql查看当前执行线程_关闭当前的某些线程 show processlist_kill

    每个与mysqld的连接都在一个独立的线程里运行,您可以使用SHOW PROCESSLIST语句查看哪些线程正在运行,并使用KILL thread_id语句终止一个线程. 如果您拥有SUPER权限,您 ...

  4. ASP.net MVC5 Code First填充测试数据到数据库

    问题的产生  最近在看Adam Freeman的“Pro ASP.NET MVC5”,于是在工作机上面搭建了相应的运行环境,但是在自己的机器上面只有代码,没有数据库.记得在code first中可以新 ...

  5. photoshop cc 安装失败 2%

    photoshop cc 安装失败 2%   C盘--Program Files---Common Files--Adobe--caps ,把这个文件夹中的文件全部删除,然后再安装     C:\Pr ...

  6. Linux系统命令 3

    1.vmstat命令监控系统资源[root@localhost ~]#vmstat [刷新延时 刷新次数] 例如:[root@localhost proc]#vmstat 1 3 2.dmesg开机时 ...

  7. 【只要有ENA千万别用NCBI】拆分SRA文件,通过SRAtoolkits

    只要有ENA千万别用NCBI!!!! 最近开始分析网上Download的数据,一开始用人家现成的GWAS数据,后来觉得反正自己的数据到手该做的也是要做的,出来混早晚是要还的,所以就开始从头分析一些SR ...

  8. Python sqlalchemy orm 多对多外键关联

    多对多外键关联 注:使用三张表进行对应关联 实现代码: # 创建3个表 配置外键关联 # 调用Column创建字段 加类型 from sqlalchemy import Table, Column, ...

  9. mac 遇到的奇怪问题?

    1: 卸载 xcode,发现git报错了. mac git xcrun error active developer path 错误 解决办法:sudo xcode-select -switch / ...

  10. SpringIOC和AOP原理 设计模式

    SpringIOC的特点 在接触Spring的过程中,听到最多的无非两个名词,一个是控制反转一个是依赖注入.实际这是一个意思,控制反转代表原来由程序本身去控制对象之间的依赖关系的这种格局被反转了,通过 ...