题目描述

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

  1. 插入x数

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

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

  4. 查询排名为x的数

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

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

输入输出格式

输入格式:

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1≤opt≤6 1 \leq opt \leq 6 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 n \leq 100000 n≤100000

2.每个数的数据范围: $[-{10}^7, {10}^7]$

题解:

模板题,用的是fhq_treap。

 //Never forget why you start
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctime>
#define ll(x) tre[x].child[0]
#define rr(x) tre[x].child[1]
#define son(x,t) tre[x].child[t]
using namespace std;
int n,m,cnt,root;
struct Treap{
int child[],x,size,rev;
}tre[];
void push_up(int root){
tre[root].size=tre[ll(root)].size+tre[rr(root)].size+;
}
int newnode(int x){
cnt++;
tre[cnt].size=;
tre[cnt].rev=rand();
tre[cnt].x=x;
return cnt;
}
void split(int now,int k,int &x,int &y){
if(!now)x=y=;
else{
if(tre[now].x<=k)
x=now,split(rr(now),k,rr(now),y);
else
y=now,split(ll(now),k,x,ll(now));
push_up(now);
}
}
int merge(int x,int y){
if(!x||!y)return x+y;
if(tre[x].rev<tre[y].rev){
rr(x)=merge(rr(x),y);
push_up(x);
return x;
}
else{
ll(y)=merge(x,ll(y));
push_up(y);
return y;
}
}
int find(int root,int k){
int y=tre[ll(root)].size;
if(y+==k)return root;
else if(y>=k)return find(ll(root),k);
else find(rr(root),k-y-);
}
int main(){
int i,j,a,b,c;
srand(time());
scanf("%d",&n);
while(n--){
scanf("%d%d",&i,&j);
if(i==){
split(root,j,a,b);
root=merge(merge(a,newnode(j)),b);
}
if(i==){
split(root,j,a,c);
split(a,j-,a,b);
b=merge(ll(b),rr(b));
root=merge(merge(a,b),c);
}
if(i==){
split(root,j-,a,b);
printf("%d\n",tre[a].size+);
root=merge(a,b);
}
if(i==){
printf("%d\n",tre[find(root,j)].x);
}
if(i==){
split(root,j-,a,b);
printf("%d\n",tre[find(a,tre[a].size)].x);
root=merge(a,b);
}
if(i==){
split(root,j,a,b);
printf("%d\n",tre[find(b,)].x);
root=merge(a,b);
}
}
return ;
}

最新文章

  1. bindActionCreators
  2. Itext Demo
  3. ProgressBar 详解
  4. 类模板Queue的实现
  5. 通过Mac远程调试iPhone/iPad上的网页(转)
  6. 2016 版 Laravel 系列入门教程(四)【最适合中国人的 Laravel 教程】
  7. (转)json+flexgrid+jbox组合运用页面刷新&lt;jsp&gt;
  8. Sqli-labs less 19
  9. OAuth 2.0
  10. 修改cmd字体为Consolas
  11. 关于开源框架GPUImage 的简单说明
  12. 【 js 基础 】【 源码学习 】 setTimeout(fn, 0) 的作用
  13. [js高手之路]Node.js模板引擎教程-jade速学与实战4-模板引用,继承,插件使用
  14. 自学Zabbix3.1-语言切换
  15. 阿里巴巴的开源项目Druid(关于数据库连接)
  16. CF396C On Changing Tree
  17. 通过DeviceIoControl读磁盘的方式读取独占文件内容
  18. spring&#160;中IOC实验(一)
  19. bazel build //tensorflow/examples/android:tensorflow_demo报错: fatal error: &#39;cuda_runtime.h&#39; file not found
  20. OpenLdap+MySQL笔记

热门文章

  1. uboot和内核分区的修改
  2. springmvc chrome jsonviewer 一起请求 重复提提交 controller重复执行 2次执行
  3. [转]VS 2013 未找到与约束contractname Microsoft.VisualStudio.Utilities.IContentTypeRegistryService...匹配的导出
  4. 通过HBase Shell与HBase交互
  5. 《精通Spring4.X企业应用开发实战》读后感第六章(国际化)
  6. storm启动supervisor源码分析-supervisor.clj
  7. C# 生成chm帮助文件
  8. Raising Modulo Numbers(ZOJ 2150)
  9. Maven核心知识
  10. express+vue-cli实现前后端分离交互小例