题目描述

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

插入 xx 数

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

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

查询排名为 xx 的数

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

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

输入输出格式

输入格式:

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

输出格式:

对于操作 3,4,5,63,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 100000 n≤100000

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

7

,10

7

]

来源:Tyvj1728 原名:普通平衡树

#include<iostream>
#include<cstdio>
#include<cstring> using namespace std;
const int MAXN = 100005;
const int inf = 0x7f7f7f7f; struct Node{
int v,fa;
int ch[2];
int sum;
int recy;
}node[MAXN]; int n,cnt,points; inline void update(int x){
node[x].sum=node[node[x].ch[1]].sum+node[node[x].ch[0]].sum+node[x].recy;
} inline bool jud(int x){
return node[node[x].fa].ch[0]==x?0:1;
} inline void connect(int x,int f,int son){
node[x].fa=f;
node[f].ch[son]=x;
} inline void rotate(int x){
int y=node[x].fa;
int mroot=node[y].fa;
int mrootson=jud(y);
int yson=jud(x);
int oth=node[x].ch[yson^1];
connect(oth,y,yson);
connect(y,x,(yson^1));
connect(x,mroot,mrootson);
update(y);update(x);
} inline void splay(int at,int to){
to=node[to].fa;
while(node[at].fa!=to){
int up=node[at].fa;
if(node[up].fa==to) rotate(at);
else if(jud(up)==jud(at)){
rotate(up);
rotate(at);
}
else{
rotate(at);
rotate(at);
}
}
} inline int crepoint(int x,int f){
node[++cnt].v=x;
node[cnt].fa=f;
node[cnt].sum=1;
node[cnt].recy=1;
return cnt;
} inline void destroy(int x){
node[x].v=node[x].fa=node[x].sum=node[x].recy=node[x].ch[0]=node[x].ch[1]=0;
if(x==cnt) cnt--;
} inline int find(int v){
int now=node[0].ch[1];
while(1){
if(node[now].v==v){
splay(now,node[0].ch[1]);
return now;
}
int nxt=v<node[now].v?0:1;
if(!node[now].ch[nxt]) return 0;
now=node[now].ch[nxt];
}
} inline int build(int x){
points++;
if(cnt==0){
node[0].ch[1]=1;
crepoint(x,0);
}
else{
int now=node[0].ch[1];
while(1){
node[now].sum++;
if(x==node[now].v){
node[now].recy++;
return now;
}
int nxt=x<node[now].v?0:1;
if(!node[now].ch[nxt]){
crepoint(x,now);
node[now].ch[nxt]=cnt;
return cnt;
}
now=node[now].ch[nxt];
}
}
return 0;
} inline void push(int x){
int add=build(x);
splay(add,node[0].ch[1]);
} inline void pop(int v){
int deal=find(v);
if(!deal) return;
points--;
if(node[deal].recy>1){
node[deal].recy--;
node[deal].sum--;
return;
}
if(!node[deal].ch[0]){
node[0].ch[1]=node[deal].ch[1];
node[node[0].ch[1]].fa=0;
}
else{
int lef=node[deal].ch[0];
while(node[lef].ch[1]) lef=node[lef].ch[1];
splay(lef,node[deal].ch[0]);
int rig=node[deal].ch[1];
connect(rig,lef,1);connect(lef,0,1);
update(lef);
}
destroy(deal);
} int rank(int x){
int ans=0;
int now=node[0].ch[1];
while(1){
if(node[now].v==x) return ans+node[node[now].ch[0]].sum+1;
if(now==0) return 0;
if(x<node[now].v) now=node[now].ch[0];
else{
ans+=node[node[now].ch[0]].sum+node[now].recy;
now=node[now].ch[1];
}
}
if(now) splay(now,node[0].ch[1]);
return 0;
} int atrank(int x){
if(x>points) return -inf;
int now=node[0].ch[1];
while(1){
int minn=node[now].sum-node[node[now].ch[1]].sum;
if(x>node[node[now].ch[0]].sum && x<=minn) break;
if(x<minn) now=node[now].ch[0];
else{
x=x-minn;
now=node[now].ch[1];
}
}
splay(now,node[0].ch[1]);
return node[now].v;
} inline int lower(int x){
int now=node[0].ch[1];
int res=-inf;
while(now){
if(node[now].v<x && node[now].v>res) res=node[now].v;
if(x>node[now].v) now=node[now].ch[1];
else now=node[now].ch[0];
}
return res;
} inline int upper(int x){
int now=node[0].ch[1];
int res=inf;
while(now){
if(node[now].v>x && node[now].v<res) res=node[now].v;
if(x<node[now].v) now=node[now].ch[0];
else now=node[now].ch[1];
}
return res;
} int main(){
scanf("%d",&n);
push(inf);push(-inf);
for(register int i=1;i<=n;i++){
int opt,x;
scanf("%d%d",&opt,&x);
if(opt==1) push(x);
else if(opt==2) pop(x);
else if(opt==3) printf("%d\n",rank(x)-1);
else if(opt==4) printf("%d\n",atrank(x+1));
else if(opt==5) printf("%d\n",lower(x));
else printf("%d\n",upper(x));
}
return 0;
}

splay 模板 洛谷3369的更多相关文章

  1. 【数论】卢卡斯定理模板 洛谷P3807

    [数论]卢卡斯定理模板 洛谷P3807 >>>>题目 [题目] https://www.luogu.org/problemnew/show/P3807 [输入格式] 第一行一个 ...

  2. KMP字符串匹配 模板 洛谷 P3375

    KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.(如果 ...

  3. 在洛谷3369 Treap模板题 中发现的Splay详解

    本题的Splay写法(无指针Splay超详细) 前言 首先来讲...终于调出来了55555...调了整整3天..... 看到大部分大佬都是用指针来实现的Splay.小的只是按照Splay的核心思想和原 ...

  4. BZOJ3224 洛谷3369 Tyvj 1728 普通平衡树 splay

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3224 题意概括 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. ...

  5. 【模板】LIS模板 洛谷P1091 [NOIP2004提高组]合唱队形 [2017年4月计划 动态规划11]

    以题写模板. 写了两个:n^2版本与nlogn版本 P1091 合唱队形 题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队 ...

  6. 树链剖分模板(洛谷P3384)

    洛谷P3384 #include <bits/stdc++.h> #define DBG(x) cerr << #x << " = " < ...

  7. (treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树

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

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

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

  9. 【Splay】洛谷3372 【模板】线段树 1

    Splay区间加,询问区间和. #include<cstdio> #include<iostream> #include<cstring> #include< ...

随机推荐

  1. 使用Vue和djangoframwork完成登录页面构建 001

    使用Vue和djangoframwork完成登录页面构建 001 环境的搭建 首先,我在我的电脑的F盘创建了一个文件夹 forNote,进入到这个文件夹中 F:\forNote> vue环境的搭 ...

  2. MySql查询结果按照指定顺序排序

    Mysql这功能做的很好用啊!! 让查询结果按照指定顺序排序 --------------------------------------------------------------------- ...

  3. 「ZJOI2019」语言 解题报告

    「ZJOI2019」语言 3个\(\log\)做法比较简单,但是写起来还是有点麻烦的. 大概就是树剖把链划分为\(\log\)段,然后任意两段可以组成一个矩形,就是个矩形面积并,听说卡卡就过去了. 好 ...

  4. Android中ViewPgae中的Fragment如何确认当前页面可见的问题

    由于在ViewPage中PageAdapter来管理所有的Fragment.在加载一个Fragment的时候,会自动缓存左右几个(默认是一个)页面,此时也会调用到正常的生命周期函数,onCreate, ...

  5. 误将SELINUXTYPE看成SELINUX后,将其值改为disabled。导致操作系统服务启动,无法进入单用户模式

    环境:Redhat 6.4 ORACLE11g RAC 在安装ORACLE11g之前需要关闭操作系统的防火墙和SELinux. 1.关闭防火墙:iptables -F————————————清除防火墙 ...

  6. NX二次开发-基于NX开发向导模板的NX对Excel读写操作(OLE方式(COM组件))

    在看这个博客前,请读者先去完整看完:NX二次开发-基于MFC界面的NX对Excel读写操作(OLE方式(COM组件))https://ufun-nxopen.blog.csdn.net/article ...

  7. 搭建本地 8.8 W 乌云漏洞库

    这个是关于两个图片马的帖子. https://zhuanlan.zhihu.com/p/27486144 这个是开源地址: https://github.com/m0l1ce/wooyunallbug ...

  8. 解决Python报错:local variable 'xxx' referenced before assignment(引)

    解决Python报错:local variable 'xxx' referenced before assignment(引) 解决Python报错:local variable 'xxx' refe ...

  9. 使用java.util.Properties工具制作自定义访问配置文件信息

    import ch.qos.logback.classic.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; im ...

  10. VMware Workstation 无法打开内核设备:\\Global\\vmx86

    解决方法:win10系统,打开“服务”后右击选择使用管理员打开.然后在一大串服务中找到vm开头的服务项,全部都启动.重新启动vm就ok了(vm需要以管理员身份打开).不用复杂的代码!!