BZOJ1861[Zjoi2006]书架——非旋转treap
题目描述
小T有一个很大的书柜。这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列。她用1到n的正整数给每本书都编了号。 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本。由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置。不过小T的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时的位置附近,比如说她拿的时候这本书上面有X本书,那么放回去时这本书上面就只可能有X-1、X或X+1本书。 当然也有特殊情况,比如在看书的时候突然电话响了或者有朋友来访。这时候粗心的小T会随手把书放在书柜里所有书的最上面或者最下面,然后转身离开。 久而久之,小T的书柜里的书的顺序就会越来越乱,找到特定的编号的书就变得越来越困难。于是她想请你帮她编写一个图书管理程序,处理她看书时的一些操作,以及回答她的两个提问:(1)编号为X的书在书柜的什么位置;(2)从上到下第i本书的编号是多少。
输入
第一行有两个数n,m,分别表示书的个数以及命令的条数;第二行为n个正整数:第i个数表示初始时从上至下第i个位置放置的书的编号;第三行到m+2行,每行一条命令。命令有5种形式: 1. Top S——表示把编号为S的书房在最上面。 2. Bottom S——表示把编号为S的书房在最下面。 3. Insert S T——T∈{-1,0,1},若编号为S的书上面有X本书,则这条命令表示把这本书放回去后它的上面有X+T本书; 4. Ask S——询问编号为S的书的上面目前有多少本书。 5. Query S——询问从上面数起的第S本书的编号。
输出
对于每一条Ask或Query语句你应该输出一行,一个数,代表询问的答案。
样例输入
1 3 2 7 5 8 10 4 9 6
Query 3
Top 5
Ask 6
Bottom 3
Ask 3
Top 6
Insert 4 -1
Query 5
Query 2
Ask 2
样例输出
9
9
7
5
3
提示
数据范围
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
map<int,int>s;
int n,m;
int x,y;
char ch[10];
int ls[100010];
int rs[100010];
int size[100010];
int f[100010];
int r[100010];
int v[100010];
int cnt;
int root;
int a,b,c,d;
int build(int val)
{
int rt=++cnt;
size[rt]=1;
v[rt]=val;
r[rt]=rand();
return rt;
}
void pushup(int rt)
{
size[rt]=size[ls[rt]]+size[rs[rt]]+1;
}
int merge(int x,int y)
{
if(!x||!y)
{
return x+y;
}
if(r[x]<r[y])
{
rs[x]=merge(rs[x],y);
f[rs[x]]=x;
pushup(x);
if(!rs[x])
{
f[rs[x]]=0;
}
return x;
}
else
{
ls[y]=merge(x,ls[y]);
f[ls[y]]=y;
pushup(y);
if(!ls[y])
{
f[ls[y]]=0;
}
return y;
}
}
void split1(int rt,int &a,int &b)
{
int x=ls[rt];
int y=rs[rt];
ls[rt]=rs[rt]=0;
size[rt]=1;
while(f[rt])
{
if(rt==ls[f[rt]])
{
ls[f[rt]]=y;
f[y]=f[rt];
y=f[rt];
pushup(f[rt]);
}
else
{
rs[f[rt]]=x;
f[x]=f[rt];
x=f[rt];
pushup(f[rt]);
}
rt=f[rt];
}
a=x;
b=y;
}
void split2(int rt,int &x,int &y,int k)
{
if(!rt)
{
x=y=0;
return ;
}
if(size[ls[rt]]>=k)
{
y=rt;
split2(ls[rt],x,ls[y],k);
f[ls[y]]=y;
pushup(rt);
}
else
{
x=rt;
split2(rs[rt],rs[x],y,k-size[ls[rt]]-1);
f[rs[x]]=x;
pushup(rt);
}
}
int query(int rt,int k)
{
if(size[ls[rt]]>=k)
{
return query(ls[rt],k);
}
else if(size[ls[rt]]+1==k)
{
return rt;
}
else
{
return query(rs[rt],k-size[ls[rt]]-1);
}
}
int main()
{
srand(12378);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
s[x]=build(x);
root=merge(root,s[x]);
}
while(m--)
{
scanf("%s",ch);
if(ch[0]=='I')
{
scanf("%d%d",&x,&y);
if(y==0)
{
continue;
}
x=s[x];
split1(x,a,b);
int num=size[a];
root=merge(merge(a,x),b);
if(y==-1)
{
split2(root,a,b,num-1);
split2(b,b,c,1);
split2(c,c,d,1);
root=merge(merge(a,c),merge(b,d));
}
else
{
split2(root,a,b,num);
split2(b,b,c,1);
split2(c,c,d,1);
root=merge(merge(a,c),merge(b,d));
}
}
else if(ch[0]=='T')
{
scanf("%d",&x);
x=s[x];
split1(x,a,b);
root=merge(x,merge(a,b));
}
else if(ch[0]=='B')
{
scanf("%d",&x);
x=s[x];
split1(x,a,b);
root=merge(merge(a,b),x);
}
else if(ch[0]=='A')
{
scanf("%d",&x);
x=s[x];
split1(x,a,b);
printf("%d\n",size[a]);
root=merge(merge(a,x),b);
}
else
{
scanf("%d",&x);
printf("%d\n",v[query(root,x)]);
}
}
}
BZOJ1861[Zjoi2006]书架——非旋转treap的更多相关文章
- [bzoj1861][Zjoi2006]Book 书架_非旋转Treap
Book 书架 bzoj-1861 Zjoi-2006 题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底):将指定编号元素左右篡位:查询指定编号元素位置:查询指定数量位置元素编号. ...
- 非旋转Treap:用运行时间换调试时间的有效手段
非旋转Treap:用运行时间换调试时间的有效手段 Hello大家好,我们今天来聊一聊非旋转Treap. 相信各位或多或少都做过些序列上的问题.如果水题我们考虑暴力:不强制在线我们可能用过莫队和待修 ...
- [bzoj3173]最长上升子序列_非旋转Treap
最长上升子序列 bzoj-3173 题目大意:有1-n,n个数,第i次操作是将i加入到原有序列中制定的位置,后查询当前序列中最长上升子序列长度. 注释:1<=n<=10,000,开始序列为 ...
- 关于非旋转treap的学习
非旋转treap的操作基于split和merge操作,其余操作和普通平衡树一样,复杂度保证方式与旋转treap差不多,都是基于一个随机的参数,这样构出的树树高为\(logn\) split 作用:将原 ...
- [Codeforces702F]T-Shirts——非旋转treap+贪心
题目链接: Codeforces702F 题目大意:有$n$种T恤,每种有一个价格$c_{i}$和品质$q_{i}$且每种数量无限.现在有$m$个人,第$i$个人有$v_{i}$元,每人每次会买他能买 ...
- BZOJ5063旅游——非旋转treap
题目描述 小奇成功打开了大科学家的电脑. 大科学家打算前往n处景点旅游,他用一个序列来维护它们之间的顺序.初 始时,序列为1,2,...,n. 接着,大科学家进行m次操作来打乱顺序.每次操作有6步: ...
- BZOJ3223文艺平衡树——非旋转treap
此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...
- BZOJ3224普通平衡树——非旋转treap
题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...
- [NOIP]2017列队——旋转treap/非旋转treap
Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为m. 为了便 ...
随机推荐
- 阅读Cortex-A53 Technical Reference Manual笔记
1. 前言 一颗芯片最主要的就是CPU核了,处理CPU Core之外,还存在很多其他IP,包括Graphical.Multimedia.Memory Controller.USB Controller ...
- SecureRandom
我们知道,Random类中实现的随机算法是伪随机,也就是有规则的随机.在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字. 相同种子数的Ra ...
- 分析网络流量Capsa笔记
Capsa是一款网络分析仪,允许您监控网络流量,解决网络问题并分析数据包.通过提供生动的图表,通过设计良好的GUI提供丰富的统计信息和实时警报,Capsa可让IT管理员实时识别,诊断和解决有线和无线网 ...
- Zookeeper-基本概念
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务.它是一个典型的分布式数据一致性的解决方案,分布式应用可以基于它实现诸如数据发布/订阅.负载均衡.命名服务.分布式协调/通知.集群管理 ...
- JAVA CAS原理浅谈
java.util.concurrent包完全建立在CAS之上的,没有CAS就不会有此包.可见CAS的重要性. CAS CAS:Compare and Swap, 翻译成比较并交换. java.uti ...
- mysql主从同步(5)-同步延迟状态考量(seconds_behind_master和pt-heartbea)
一般情况下,我们是通过"show slave status \G;"提供的Seconds_Behind_Master值来衡量mysql主从同步的延迟情况.具体说明见:mysql主从 ...
- 完整部署CentOS7.2+OpenStack+kvm 云平台环境(2)--云硬盘等后续配置
继上一篇博客介绍了完整部署CentOS7.2+OpenStack+kvm 云平台环境(1)--基础环境搭建,本篇继续讲述后续部分的内容 1 虚拟机相关1.1 虚拟机位置介绍 openstack上创建的 ...
- git 配置别名
对于常用的git的命令,可以通过配置别名的方式,提高工作效率. $ git config --global alias.co checkout //执行git co 相当于git checkout $ ...
- M2阶段事后总结
设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述?我们的主要任务是将35w+个符合条件的网页,问答,文章放入数据库:爬取功能定义为以下几种:通用型爬取 ...
- 广商博客冲刺第四五天new
第三天沖刺傳送門 第六七天沖刺傳送門 以上的前台设计架构已经完成了,现在来完成前台的安卓设计. 首先我们配置了Android SDK Manager 使得程序能在安卓环境下运行. 这就完成了前台安卓的 ...