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. 为了便 ...
随机推荐
- Java中没有引用传递只有值传递(在函数中)
◆传参的问题 引用类型(在函数调用中)的传参问题,是一个相当扯的问题.有些书上说是传值,有些书上说是传引用.搞得Java程序员都快成神经分裂了.所以,我们最后来谈一下“引用类型参数传递”的问题. 如下 ...
- python里面 循环明细对比 相同人员明细,生成同一订单里面
#2018-04-16 def action_create_purc(self,cr,uid,ids,context=None): mrp_origin_obj=self.browse(cr,uid, ...
- Codechef MGCHGYM Misha and Gym 容斥、背包、Splay
VJ传送门 简化题意:给定一个长度为\(N\)的数列,\(Q\)个操作: \(1\,x\,a\).将数列中第\(x\)个元素改为\(a\) \(2\,l\,r\).反转子序列\([l,r]\) \(3 ...
- React-JSX简介
JSX 本身其实也是一种表达式 在编译之后呢,JSX 其实会被转化为普通的 JavaScript 对象.这也就意味着,你其实可以在 if 或者 for 语句里使用 JSX,将它赋值给变量,当作参数传入 ...
- 一次线上redis实例cpu占用率过高问题优化(转)
前情提要: 最近接了大数据项目的postgresql运维,刚接过来他们的报表系统就出现高峰期访问不了的问题,报表涉及实时数据和离线数据,离线读pg,实时读redis.然后自然而然就把redis也挪到我 ...
- redis调优的实战经验
本文根据redis的info命令查看redis的内存使用情况以及state状态,来观察redis的运行情况以及需要作出的相应优化. info 1.memory used_memory:13409011 ...
- 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-5
来个目录吧: 第一章-入门 第二章- Entity Framework Core Nuget包管理 第三章-创建.修改.删除.查询 第四章-排序.过滤.分页.分组 第五章-迁移,EF Core 的co ...
- 记一次在.NET成长之路上的下午茶
在2017年2月25日我和李海国有幸与阳铭.朱永光两位大哥喝了一次下午茶.熟悉ABP框架的朋友呢知道阳铭远在上海,所以个人很是珍惜这次机会.朱永光大哥是微软MVP,之前是启路科技的CTO,目前在微软. ...
- ul ol li的序号编号样式
序号样式例子,下面是html代码(做参考) <ol> <li>列表内容列表内容列表内容列表</li> <li>列表内容列表内容列表内容列表</li ...
- linux内核期中总结
20135132陈雨鑫 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ...