loj #107. 维护全序集
#107. 维护全序集
题目描述
这是一道模板题,其数据比「普通平衡树」更强。
如未特别说明,以下所有数据均为整数。
维护一个多重集 S SS ,初始为空,有以下几种操作:
- 把 x xx 加入 S SS
- 删除 S SS 中的一个 x xx,保证删除的 x xx 一定存在
- 求 S SS 中第 k kk 小
- 求 S SS 中有多少个元素小于 x xx
- 求 S SS 中小于 x xx 的最大数
- 求 S SS 中大于 x xx 的最小数
操作共 n nn 次。
输入格式
第一行一个整数 n nn,表示共有 n nn 次操作 。
接下来 n nn 行,每行为以下几种格式之一 :
0 x
,把 x xx 加入 S SS1 x
,删除 S SS 中的一个 x xx,保证删除的数在 S SS 中一定存在2 k
,求 S SS 中第 k kk 小的数,保证要求的数在 S SS 中一定存在3 x
,求 S SS 中有多少个数小于 x xx4 x
,求 S SS 中小于 x xx 的最大数,如果不存在,输出 −1 -1−15 x
,求 S SS 中大于 x xx 的最小数,如果不存在,输出 −1 -1−1
输出格式
对于每次询问,输出单独一行表示答案。
样例
样例输入
5
0 3
0 4
2 2
1 4
3 3
样例输出
4
0
数据范围与提示
1≤n≤3×105,0≤x≤109 1 \leq n \leq 3 \times 10 ^ 5, 0 \leq x \leq 10 ^ 91≤n≤3×105,0≤x≤109
#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x7fffffff
#define maxn 400010
using namespace std;
int m,rt,son[maxn][],fa[maxn],val[maxn],cnt[maxn],sz[maxn],size;
void update(int x){
sz[x]=sz[son[x][]]+sz[son[x][]]+cnt[x];
}
void rotate(int x,int &k){
int y=fa[x],z=fa[fa[x]],l,r;
if(son[y][]==x)l=;else l=;r=l^;
if(y==k)k=x;
else son[z][son[z][]==y]=x;
fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
son[y][l]=son[x][r];son[x][r]=y;
update(y);update(x);
}
void splay(int x,int &k){
while(x!=k){
int y=fa[x],z=fa[fa[x]];
if(y!=k){
if((son[z][]==y)^(son[y][]==x))rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
void Insert(int v){
int y=,k=rt;
while(k&&val[k]!=v)y=k,k=son[k][v>val[k]];
if(k)cnt[k]++;
else {
k=++size;
cnt[k]=sz[k]=;
fa[k]=y;val[k]=v;
if(y)son[y][v>val[y]]=k;
}
splay(k,rt);
}
int find2(int x){
x++;int k=rt;
if(sz[k]<x)return ;
while(){
if(sz[son[k][]]<x&&sz[son[k][]]+cnt[k]>=x)return k;
if(sz[son[k][]]>=x)k=son[k][];
else x-=sz[son[k][]]+cnt[k],k=son[k][];
}
return k;
}
void find1(int x){
int k=rt;if(!k)return;
while(son[k][x>val[k]]&&val[k]!=x)
k=son[k][x>val[k]];
splay(k,rt);
}
int nxt(int x,int f){
find1(x);//if(!rt)return 0;
if((val[rt]>x&&f)||(val[rt]<x&&!f))return rt;
int k=son[rt][f];
while(son[k][f^])k=son[k][f^];
return k;
}
void del(int v){
find1(v);
int x=rt,k;
if(cnt[rt]>){cnt[rt]--;sz[rt]--;return;}
if(son[rt][]*son[rt][]==){
rt=son[rt][]+son[rt][];
}
else {
k=son[rt][];
while(son[k][])k=son[k][];sz[k]+=sz[son[x][]];
fa[son[x][]]=k;
son[k][]=son[x][];rt=son[x][];
}
fa[rt]=;splay(k,rt);
}
void debug(){
printf("%d ",val[rt]); }
int main(){
scanf("%d",&m);
Insert(0x7fffffff);Insert(-0x7fffffff);
int op,x;
while(m--){
scanf("%d%d",&op,&x);
if(op==)Insert(x);
if(op==)del(x);
if(op==)printf("%d\n",val[find2(x)]);
if(op==){
find1(x);
int ans=sz[son[rt][]]-;
if(val[rt]<x)ans+=cnt[rt];
printf("%d\n",ans);
}
if(op==){
int w=val[nxt(x,)];
if(w==INF||w==-INF)puts("-1");
else printf("%d\n",w);
}
if(op==){
int w=val[nxt(x,)];
if(w==INF||w==-INF)puts("-1");
else printf("%d\n",w);
}
}
return ;
}
loj #107. 维护全序集的更多相关文章
- 2018.07.24 loj#107. 维护全序集(非旋treap)
传送门 就是普通平衡树,可以拿来练非旋treap" role="presentation" style="position: relative;"&g ...
- LOJ#107. 维护全序集(FHQ Treap)
题面 传送门 题解 板子,没啥好说的 //minamoto #include<bits/stdc++.h> #define R register #define inline __inli ...
- LibreOJ #107. 维护全序集
内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 匿名 splay模板题 屠龙宝刀点击就送 #include <cstdio&g ...
- LOJ107. 维护全序集【树状数组维护全序集】
题目描述 这是一道模板题,其数据比「普通平衡树」更强. 如未特别说明,以下所有数据均为整数. 维护一个多重集 S ,初始为空,有以下几种操作: 把 x 加入 S 删除 S 中的一个 x,保证删除的 x ...
- 【GXZ的原创】平衡树性能测试
本文作者为 GXZlegend ,转载请注明 出处 ,谢谢! 〇.序言 前些日子闲的蛋疼做了个平衡树性能测试... 主要是因为学会的平衡树越来越多,做题时却不知道写哪个... 本想结合效率和代码复杂度 ...
- LOJ 121 「离线可过」动态图连通性——LCT维护删除时间最大生成树 / 线段树分治
题目:https://loj.ac/problem/121 离线,LCT维护删除时间最大生成树即可.注意没有被删的边的删除时间是 m+1 . 回收删掉的边的节点的话,空间就可以只开 n*2 了. #i ...
- Loj 2230. 「BJOI2014」大融合 (LCT 维护子树信息)
链接:https://loj.ac/problem/2230 思路: 设立siz数组保存虚点信息,sum表示总信息 维护子树信息link操作和access操作需要进行一些改动 可参考博客:https: ...
- LOJ #2769 -「ROI 2017 Day 1」前往大都会(单调栈维护斜率优化)
LOJ 题面传送门 orz 斜率优化-- 模拟赛时被这题送走了,所以来写篇题解( 首先这个最短路的求法是 trivial 的,直接一遍 dijkstra 即可( 重点在于怎样求第二问.注意到这个第二问 ...
- LOJ 164 【清华集训2015】V——线段树维护历史最值
题目:http://uoj.ac/problem/164 把操作改成形如 ( a,b ) 表示加上 a 之后对 b 取 max 的意思. 每个点维护当前的 a , b ,还有历史最大的 a , b 即 ...
随机推荐
- temp3
- 【知识碎片】CSS 篇
1.CSS达到截取效果 地方卡机了会计师的立法及 => 地方卡机了... max-width: 400px; overflow: hidden; white-space: nowrap; t ...
- GDB常用命令简介
1.启动调试程序 gdb 调试对象,例如gdb app 2.运行程序 run 或这简写为r 3.设置断点 有几种不同的方式 1)break line 2) break file:line 3) bre ...
- 3-1 Git下载与安装
https://desktop.github.com/
- php 读取和下载execl
最近用到php 对excel 的操作 下来 小弟为大家 先贴一下自己的代码 有什么补充的 大神们请指点下.感激不尽. 我用的是yii2 yii2中有类 phpexcel 先说说下载吧. 首先下载 ...
- Python04 range()方法的使用、turtle.textinput()方法和write()的使用、turtle.numinput()的使用
1 range() 方法的使用 1.1 range方法介绍 range方法会返回一个range类型的对象,该对象会根据range方法的参数产生一些列整型数据 技巧01:range方法有三个参数,第一个 ...
- 485. Max Consecutive Ones最长的连续1的个数
[抄题]: Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Inpu ...
- css常见问题解决方法
设置方法: div内的img和span都需要设置vertical-align:middle; 解决inline-block的空格: http://www.w3cplus.com/css/fightin ...
- SparkR 读取数据& Spark运行的配置
1.本地LOCAL环境安装Spark并试运行配置(在Ubuntu系统下例子) # 打开文件配置环境变量: JAVA,SCALA,SPARK,HADOOP,SBT gedit /etc/profile ...
- Mybatis——缓存机制
MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制.缓存可以极大的提升查询效率. MyBatis系统中默认定义了两级缓存. 一级缓存和二级缓存. 1.默认情况下,只有一级缓存( ...