题目描述

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

插入x数

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

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

查询排名为x的数

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

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

输入输出格式

输入格式:

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

n的数据范围:n≤100000

code:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<ctime>
using namespace std; const int MAX=200010; int n,opt,x,root,sz;
int node[MAX][2],size[MAX],fa[MAX],cnt[MAX],key[MAX]; inline void clear(int x) {
node[x][1]=node[x][0]=size[x]=fa[x]=cnt[x]=key[x]=0;
} inline bool get(int x) {
return node[fa[x]][1]==x;
} inline void update(int x){
if(x) {
size[x]=cnt[x];
if(node[x][1]) size[x]+=size[node[x][1]];
if(node[x][0]) size[x]+=size[node[x][0]];
}
} inline void rotate(int x) {
int old=fa[x],oldf=fa[old],which=get(x);
node[old][which]=node[x][which^1]; fa[node[old][which]]=old;
fa[old]=x; node[x][which^1]=old;
fa[x]=oldf;
if(oldf) node[oldf][node[oldf][1]==old]=x;
update(old);update(x);
} inline void splay(int x) {
for(int f;f=fa[x];rotate(x))
if(fa[f]){
if(get(x)==get(f)) rotate(f);
else rotate(x);
}
root=x;
} inline void insert(int x) {
if(!root) {
sz++;root=sz;
node[sz][0]=node[sz][1]=fa[sz]=0;
size[sz]=cnt[sz]=1;
key[sz]=x;
return ;
}
int now=root,f=0;
while(1) {
if(key[now]==x) {
cnt[now]++;update(now);update(f);splay(now);break;
}
f=now;
now=node[now][key[now]<x];
if(now==0) {
sz++;
node[sz][0]=node[sz][1]=0;
size[sz]=cnt[sz]=1;
fa[sz]=f;key[sz]=x;
node[f][key[f]<x]=sz;
update(f);
splay(sz);//为pre和next做准备
break;
}
}
} inline int find1(int x) {
int ans=0,now=root;
while(1){
if(x<key[now]) now=node[now][0];
else {
ans+=node[now][0]?size[node[now][0]]:0;
if(x==key[now]) {
splay(now);
return ans+1;
}
else {
ans+=cnt[now];
now=node[now][1];
}
}
}
} inline int find2(int x) {
int now=root;
while(1){
if(node[now][0]&&x<=size[node[now][0]])
now=node[now][0];
else {
int temp=(node[now][0]?size[node[now][0]]:0)+cnt[now];
if(x<=temp) return key[now];
x-=temp,now=node[now][1];
}
}
} inline int pre() {
int now=node[root][0];
while(node[now][1]) now=node[now][1];
return now;
} inline int next() {
int now=node[root][1];
while(node[now][0]) now=node[now][0];
return now;
} inline void del(int x) {
find1(x);
if(cnt[root]>1) {
cnt[root]--;
update(root);
}
else if(!node[root][0]&&!node[root][1]) {
clear(root);root=0;
}
else if(!node[root][0]) {
int old=root;
root=node[root][1];
fa[root]=0;
clear(old);
}
else if(!node[root][1]) {
int old=root;
root=node[root][0];
fa[root]=0;
clear(old);
}
else {
int lbig=pre(),old=root;
splay(lbig);
node[root][1]=node[old][1];
fa[node[old][1]]=root;
clear(old);
update(root);
}
return ;
} int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%d %d",&opt,&x);
switch(opt) {
case 1:insert(x);break;
case 2:del(x);break;
case 3:printf("%d\n",find1(x));break;
case 4:printf("%d\n",find2(x));break;
case 5:insert(x);printf("%d\n",key[pre()]);del(x);break;
case 6:insert(x);printf("%d\n",key[next()]);del(x);break;
}
}
return 0;
}

P3369 【模板】普通平衡树 (splay 模板)的更多相关文章

  1. luoguP3391[模板]文艺平衡树(Splay) 题解

    链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...

  2. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  3. [luogu3369/bzoj3224]普通平衡树(splay模板、平衡树初探)

    解题关键:splay模板题整理. 如何不加入极大极小值?(待思考) #include<cstdio> #include<cstring> #include<algorit ...

  4. bzoj3224 普通平衡树 splay模板

    题目传送门 题目大意:完成一颗splay树. 思路:模板题,学着还是很有意思的. 学习splay树:蒟蒻yyb 该题模板:汪立超 #include<bits/stdc++.h> #defi ...

  5. bzoj3224 普通平衡树(splay 模板)

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 11427  Solved: 4878[Submit][St ...

  6. 洛谷.3369.[模板]普通平衡树(Splay)

    题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...

  7. 洛谷.3391.[模板]文艺平衡树(Splay)

    题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...

  8. [bzoj3224]Tyvj 1728 普通平衡树——splay模板

    题目 你需要写一种数据结构支援以下操作. 插入元素. 删除元素. 查询元素的排名. 查询第k小的元素. 查询元素前趋. 查询元素后继. 题解 BBST裸题. 代码 #include <cstdi ...

  9. 【洛谷P3369】普通平衡树——Splay学习笔记(一)

    二叉搜索树(二叉排序树) 概念:一棵树,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉搜索树 ...

随机推荐

  1. HDU 1599

    裸的FLOYD 求最小环. #include <iostream> #include <cstdio> using namespace std; ; ; int n,m,min ...

  2. webbench压力測试工具

    apache的測试工具ab 在并发100个以上后会出现错误.网上也有非常多改ab源代码来解禁的. 只是还是推荐一款比較好用的压力測试工具webbench wget http://blog.zyan.c ...

  3. 将linux下的rm命令改造成移动文件至回收站

    将linux下的rm命令改造成移动文件至回收站 rm是Linux下文件删除的命令,它是Linux下非常强大却又非常危险的一条命令,特别是rm -rf有时候强大到让你欲哭无泪,当你想清除当前目录下的所有 ...

  4. 使用ssh和putty操控远程的linux server

    windows下没有openssh,今天这里使用openssh-server作为server,windows下使用putty作为client, putty主要流程分以下几步: step 1: 下载pu ...

  5. 【转】什么是P问题、NP问题和NPC问题

    原文链接:http://www.matrix67.com/blog/archives/105,感谢Matrix67,看完这篇文章终于把这个几个概念弄明白了!! 这或许是众多OIer最大的误区之一.   ...

  6. 大数据查询——HBase读写设计与实践--转

    背景介绍 本项目主要解决 check 和 opinion2 张历史数据表(历史数据是指当业务发生过程中的完整中间流程和结果数据)的在线查询.原实现基于 Oracle 提供存储查询服务,随着数据量的不断 ...

  7. DB2大数据量优化查询解决方案

    利用DB2表分区的功能对大数据量的表进行分区,可以优化查询. 表分区介绍: 表分区是一种数据组织方案,它根据一列或多列中的值把表数据划分为多个称为数据分区 的存储对象. (我觉得表分区就类似于Wind ...

  8. (转)vue router 如何使用params query传参,以及有什么区别

    写在前面: 传参是前端经常需要用的一个操作,很多场景都会需要用到上个页面的参数,本文将会详细介绍vue router 是如何进行传参的,以及一些小细节问题.有需要的朋友可以做一下参考,喜欢的可以点波赞 ...

  9. Hibernate框架学习(十)——查询优化

    一.类级别查询 1.get方法:没有任何策略,调用即立即查询数据库加载数据. 2.load方法:是在执行时不发送任何SQL语句,返回一个对象,使用该对象时才执行查询:应用类级别的加载策略. 1> ...

  10. RecyclerView实现终极画廊效果 中间突出并且压住两侧布局

    先给大家上个gif 要不然下面很枯燥 忘记原来在哪里看到了..... 这个效果我找了NNNNNN长时间,,,我认为凭我现在的能力 写出来需要好久 所以 退而求其次找大神写好的... 你们不要小看了这个 ...