bzoj1861 [Zjoi2006]Book 书架 splay
Input
Output
Sample Input
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
Sample Output
9
9
7
5
3
数据范围
30%的数据,n,m < = 10000
100%的数据,n,m < = 80000
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring> using namespace std; const int NN=,inf=1e9+; int n,m,rt,sz;
int c[NN][],fa[NN],deep[NN];
int a[NN],size[NN],v[NN],pos[NN]; void update(int k)//仅仅用来得到k的大小
{
size[k]=size[c[k][]]+size[c[k][]]+;
}
void rotate(int x,int &k)//一次旋转
{
int y=fa[x],z=fa[y],l,r;
if (c[y][]==x) l=;
else l=;
r=l^;
if (y==k) k=x;
else if (c[z][]==y) c[z][]=x;
else c[z][]=x;
fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
c[y][l]=c[x][r],c[x][r]=y;
update(y),update(x);//普通的一次操作。
}
void splay(int x,int &k)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if (y!=k)
{
if (c[y][]==x^c[z][]==y)//这个是判断zig还是zag,来决定谁先交换。
rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
void build(int l,int r,int f)//l,r是表示区间,f表示根
{
if (l>r) return;
int now=l,last=f;
if (l==r)
{
v[now]=a[l],size[now]=,fa[now]=last;
if (l<f) c[last][]=now;//右边左边的问题
else c[last][]=now;
return;
}
int mid=(l+r)>>;
now=mid;
build(l,mid-,mid);build(mid+,r,mid);
v[now]=a[mid],fa[now]=last;
update(now);
if (mid<f) c[last][]=now;
else c[last][]=now;
}
int find(int k,int rank)//以k为根的树中找rank
{
int l=c[k][],r=c[k][];
if (size[l]+==rank) return k;
else if (size[l]>=rank) return find(l,rank);
else return find(r,rank-size[l]-);
}
void del(int k)
{
int x,y,z;
x=find(rt,k-),y=find(rt,k+);
splay(x,rt),splay(y,c[x][]);
z=c[y][],c[y][]=,fa[z]=size[z]=;//把前驱转到根,把后驱转到根右子树,然后根右子树左儿子就是要删除的值。
update(y),update(x);
}
void move(int k,int val)//就是将编号为k的放到val值的地方。
{
int x,y,z=pos[k],rank;
splay(z,rt);
rank=size[c[z][]]+;
del(rank);
if (val==inf) x=find(rt,n),y=find(rt,n+);
else if (val==-inf) x=find(rt,),y=find(rt,);
else x=find(rt,rank+val-),y=find(rt,rank+val);
splay(x,rt),splay(y,c[x][]);
size[z]=,fa[z]=y,c[y][]=z;
update(y),update(x);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n+;i++)//特别把1空出来,防止越界。
{
scanf("%d",&a[i]);
pos[a[i]]=i;//反向映射。
}
build(,n+,);
rt=(+n)>>;
char ch[];int S,T;
for (int i=;i<=m;i++)
{
scanf("%s%d",ch,&S);
switch(ch[])
{
case'T':move(S,-inf);break;
case'B':move(S,inf);break;
case'I':scanf("%d",&T);move(S,T);break;
case'A':splay(pos[S],rt);printf("%d\n",size[c[pos[S]][]]-);break;
case'Q':printf("%d\n",v[find(rt,S+)]);break;
}
}
}
bzoj1861 [Zjoi2006]Book 书架 splay的更多相关文章
- bzoj1861 [Zjoi2006]Book 书架——splay
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1861 发现自己想splay的时候总是纠结那个点权是什么,因为splay原本是二分查找树... ...
- [BZOJ1861][Zjoi2006]Book 书架
[BZOJ1861][Zjoi2006]Book 书架 试题描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候 ...
- [bzoj1861][Zjoi2006]Book 书架_非旋转Treap
Book 书架 bzoj-1861 Zjoi-2006 题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底):将指定编号元素左右篡位:查询指定编号元素位置:查询指定数量位置元素编号. ...
- BZOJ 1861: [Zjoi2006]Book 书架 splay
1861: [Zjoi2006]Book 书架 Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书 ...
- fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架
题面:P2596 [ZJOI2006]书架 题解:记录每本书对应的节点编号 普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中) ...
- BZOJ 1861: [Zjoi2006]Book 书架 | SPlay 板题
#include<cstdio> #include<algorithm> #include<cstring> #define N 80010 #define whi ...
- BZOJ 1861 [Zjoi2006]Book 书架 ——Splay
[题目分析] 模板题目. 首尾两个虚拟结点,十分方便操作. [代码] #include <cstdio> #include <cstring> #include <cma ...
- 并不对劲的bzoj1861: [Zjoi2006]Book 书架
传送门-> 这题的正确做法是splay维护这摞书. 但是并不对劲的人选择了暴力(皮这一下很开心). #include<algorithm> #include<cmath> ...
- BZOJ1861[ZJOI2006]Book书架
Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下 ...
随机推荐
- 实现BX的内容加上123 并把和送到寄存器AX
① 一条指令 ] ②两条指令 MOV AX,BX Tips: LEA指令与MOV指令的区别: ① MOV指令是 数据 传送指令-------传送数据 LEA指令是 有效地址 传送指令 ...
- FreeBSD--常用命令
FreeBSD常用命令 查看网络流量 a.systat -if 1 (1表示1s刷新屏幕一次) b.netstat 1 # Traffic 流量 peak 峰值 average 平均值 查看进程p ...
- PHP设计者---composer
Composer 是 PHP5以上 的一个依赖管理工具.它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们.Composer 不是一个包管理器.是的,它涉及 "packages&q ...
- laravel-多条件查询并指定key输出
$room = DB::table('room') ->where(function($query) use($contList){ foreach ($contList as $k=>$ ...
- PLC状态机编程-如何在STL中使用状态机
搞PLC编程多年,一直不知道状态机,学习matlab后,发现状态机编程异常方便,过去很多编程时的疑惑豁然开朗起来.今天跟大家分享一下如何在STL中使用状态机. 下面是用状态机描述的控制任务. 这个状态 ...
- 笔记-scrapy-signal
笔记-scrapy-signal 1. scrapy singal 1.1. 信号机制 scrapy的信号机制主要由三个模块完成 signals.py 定义信号量 signalmana ...
- J2EE中getParameter与getAttribute以及对应的EL表达式
摘自http://blog.csdn.net/woshixuye/article/details/8027089 getParameter ① 得到的都是String类型的.如http://name. ...
- Android面试收集录14 Android进程间通信方式
一.使用 Intent Activity,Service,Receiver 都支持在 Intent 中传递 Bundle 数据,而 Bundle 实现了 Parcelable 接口,可以在不同的进程间 ...
- python字典的整理信息
字典的增删改查大纲 增: dic={'age':18,'name':'liu','sex':'male'} dic['high'] = 185 #没有键值对,添加 dic['age'] = 16 #有 ...
- Android快速发布项目到jcenter详解
不管别人的教程多详细,都有他们忽略的坑,所以,都要自己动手.我也是参考了许多许多的博客,弄了一上午加下午十分钟,才搞定. 参考: 下面这个是大部分的步骤 http://blog.csdn.net/zh ...