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

插入x数
删除x数(若有多个相同的数,因只删除一个)
查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
查询排名为x的数
求x的前驱(前驱定义为小于x,且最大的数)
求x的后继(后继定义为大于x,且最小的数)
输入输出格式
输入格式:
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1≤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≤100000
2.每个数的数据范围: [-{10}^7, {10}^7]

--------------------------------------------------------------------------------------

刚学的,不用旋转的TREAP

好写,主要就是split和merge两个操作。

可以实现可持久化。

可以实现区间操作。

据说,比splay要慢

--------------------------------------------------------------------------------------

  1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn=1e5+5;
4 const int inf=1e9;
5 struct node
6 {
7 int ch[2],val,rd,siz;
8 }tr[maxn];
9 int n,m,l,r;
10 int tot,root;
11 int newnode(int v)
12 {
13 ++tot;
14 tr[tot].val=v;
15 tr[tot].rd=rand();
16 tr[tot].siz=1;
17 tr[tot].ch[0]=tr[tot].ch[1]=0;
18 return tot;
19 }
20 void update(int x)
21 {
22 tr[x].siz=tr[tr[x].ch[0]].siz+tr[tr[x].ch[1]].siz+1;
23 }
24 int merge(int a,int b)
25 {
26 if(a*b==0)return a+b;
27 if(tr[a].rd<tr[b].rd)
28 {
29 tr[a].ch[1]=merge(tr[a].ch[1],b);
30 update(a);
31 return a;
32 }
33 else
34 {
35 tr[b].ch[0]=merge(a,tr[b].ch[0]);
36 update(b);
37 return b;
38 }
39 }
40 void split(int cur,int k,int &x,int &y)
41 {
42 if(!cur)x=y=0;
43 else
44 {
45 if(tr[cur].val<=k)
46 {
47 x=cur;
48 split(tr[cur].ch[1],k,tr[cur].ch[1],y);
49 }
50 else
51 {
52 y=cur;
53 split(tr[cur].ch[0],k,x,tr[cur].ch[0]);
54 }
55 update(cur);
56 }
57 }
58 void insert(int v)
59 {
60 int x,y;
61 split(root,v,x,y);
62 root=merge(merge(x,newnode(v)),y);
63 }
64 void del(int v)
65 {
66 int x,y,z;
67 split(root,v,x,z);
68 split(x,v-1,x,y);
69 y=merge(tr[y].ch[0],tr[y].ch[1]);
70 root=merge(merge(x,y),z);
71 }
72 void findrank(int v)
73 {
74 int x,y;
75 split(root,v-1,x,y);
76 printf("%d\n",tr[x].siz+1);
77 root=merge(x,y);
78 }
79 int kth(int now,int k)
80 {
81 int cur=now;
82 while(cur)
83 {
84 if(tr[tr[cur].ch[0]].siz+1==k)return tr[cur].val;
85 else if(tr[tr[cur].ch[0]].siz>=k)cur=tr[cur].ch[0];
86 else
87 {
88 k-=tr[tr[cur].ch[0]].siz+1;
89 cur=tr[cur].ch[1];
90 }
91 }
92 return -inf;
93 }
94 void pre(int v)
95 {
96 int x,y;
97 split(root,v-1,x,y);
98 printf("%d\n",kth(x,tr[x].siz));
99 root=merge(x,y);
100 }
101 void suc(int v)
102 {
103 int x,y;
104 split(root,v,x,y);
105 printf("%d\n",kth(y,1));
106 root=merge(x,y);
107 }
108 int main()
109 {
110 srand((unsigned)time(NULL));
111 int n,op,v;
112 scanf("%d",&n);
113 while(n--)
114 {
115 scanf("%d%d",&op,&v);
116 switch(op)
117 {
118 case 1:insert(v);break;
119 case 2:del(v);break;
120 case 3:findrank(v);break;
121 case 4:printf("%d\n",kth(root,v));break;
122 case 5:pre(v);break;
123 case 6:suc(v);break;
124 default:break;
125 }
126 }
127 return 0;
128 }

luogu p3369的更多相关文章

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

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

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

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

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

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

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

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

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

    题目链接:https://www.luogu.org/problemnew/show/P3369 #include <cstdio> #include <algorithm> ...

  6. luogu P3369 【模板】普通平衡树(splay)

    嘟嘟嘟 突然觉得splay挺有意思,唯一不足的是这几天是一天一道,debug到崩溃. 做了几道平衡树基础题后,对这题有莫名的自信,还算愉快的敲完了代码后,发现样例都过不去,然后就陷入了无限的debug ...

  7. 普通平衡树Tyvj1728、luogu P3369 (splay)

    存个模板,这次是splay的: 题目见这个题解: <--(鼠标移到这儿) 代码如下: #include<cstdio> #define INF 2147483647 using na ...

  8. 普通平衡树Tyvj1728、luogu P3369 (treap)

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询x数的排名(若有多个相同的数,因输出最小的排名) 查询排名为x的 ...

  9. 【luogu P3369 【模板】普通平衡树(Treap/SBT)】 模板 Scapegoat Tree

    #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> ...

  10. 【luogu P3369 【模板】普通平衡树(Treap/SBT)】 题解 pb_ds

    我永远都爱STL ! 我爱PB_DS ! #include <iostream> #include <cstdio> #include <ext/pb_ds/tree_p ...

随机推荐

  1. docker 使用笔记

    docker 使用笔记 1. 与宿主机之间拷贝文件 docker cp test.html 99f952ac05e6cd879f14aa6c9d0db02aaf498634edc4f6cdc9953c ...

  2. Java优雅停机

    Java的优雅停机通常通过注册JDK的ShootDownHook实现,当系统接受到退出指令后,首先标记系统处于退出状态,不再接受新的消息,然后将积压的消息处理完,最后调用资源回收接口将资源销毁,最后各 ...

  3. maven仲裁机制

    maven仲裁机制 玩过springboot的人都知道  springboot项目中你一般看不到大段的spring相关包 而是像 spring-boot-start一个jar包就包含spring相关的 ...

  4. Java Object to Class

    User user = new User(username,password); //添加构成JWT的参数 JwtBuilder builder = Jwts.builder().setHeaderP ...

  5. IE浏览器F12无法使用

    原文链接http://zhhll.icu/2020/04/07/windows/IE%E6%B5%8F%E8%A7%88%E5%99%A8F12%E6%97%A0%E6%B3%95%E4%BD%BF% ...

  6. PHP 清除缓存文件

    /*清除缓存文件*/ public function clearRuntime() { $this->delFileByDir(RUNTIME_PATH); $this->success( ...

  7. python中环境变量的使用

    前言 之前就经常用,今天来凑个篇数. 在开发的过程中,我们经常会将代码中某些可能更改的,比如redis地址,数据库地址,限流阈值等参数写活来提高灵活性, 传统的方式可能是写在配置文件中,比如 xml ...

  8. Thread线程源码解析,Java线程的状态,线程之间的通信

    线程的基本概念 什么是线程 现代操作系统在运行一个程序的时候,会为其创建一个进程.例如,启动一个Java程序,操作系统就会创建一个Java进程.线代操作系统调度的最小单位是线程.也叫做轻量级进程.在一 ...

  9. Redis-4.X 版本 Redis Cluster集群 (一)

    一 创建redis cluster 集群前提条件: 1 ) 每个redis node 节点采用相同的硬件配置,相同的密码. 2 ) 每个节点必须开启的参数: cluster-enabled yes # ...

  10. 实操|如何将 Containerd 用作 Kubernetes runtime

    日前专为开发者提供技术分享的又拍云 OpenTalk 公开课邀请了网易有道资深运维开发工程师张晋涛,直播分享<Containerd 上手实践 >,详细介绍 Containerd 的发展历程 ...