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在看书的时候,每次取出一本书,看完后放回书柜然后再拿下 ...
随机推荐
- php红包算法函数[优化]
php红包算法 <?php header("Content-Type: text/html;charset=utf-8");//输出不乱码,你懂的 $total=10000; ...
- 【linux】【指令】systemctl 指令部分解读
systemctl [OPTIONS...] {COMMAND} ... Query or send control commands to the systemd manager. -h --hel ...
- PHP Socket服务器搭建和测试
1.socket服务器搭建思路 1) 目的:理解socket服务器工作机制 2) 思路:创建socket -> 把socket加入连接池 -> 处理接收信息 -> 握手动作 -> ...
- Python 对象(type/object/class) 作用域 一等函数 (慕课--Python高级,IO并发 第二章)
在python中一共有两种作用域:全局作用域和函数作用域全局作用域:在全局都有效,全局作用域在程序执行时创建,在程序执行结束时销毁:所有函数以外的区域都是全局作用域:在全局作用域中定义的变量,都属于全 ...
- 霍夫圆检测 opencv
进行霍夫圆变换中有一个API:HoughCircles(). 第五个参数为double类型的minDist(),为霍夫变换检测到的圆的圆心之间的最小距离,即让算法能明显区分的两个不同圆之间的最小距离. ...
- C# 输出结果有System.Byte[]
byte[]类型直接输出或者调用ToString函数都会出现这个结果. 需要执行: byte[] a=new byte[10]; string text = "";for (int ...
- scrapy如何实现分布式爬虫
使用scrapy爬虫的时候,记录一下如何分布式爬虫问题: 关键在于多台主机协作的关键:共享爬虫队列 主机:维护爬取队列从机:负责数据抓取,数据处理,数据存储 队列如何维护:Redis队列Redis 非 ...
- 13,SQLAlchemy 增删改查 一对多 多对多
今天来聊一聊 Python 的 ORM 框架 SQLAlchemy Models 是配置和使用比较简单,因为他是Django自带的ORM框架,也正是因为是Django原生的,所以兼容性远远不如SQLA ...
- CodeForces 805F Expected diameter of a tree 期望
题意: 给出一个森林,有若干询问\(u, v\): 从\(u, v\)中所在子树中随机各选一个点连起来,构成一棵新树,求新树直径的期望. 分析: 回顾一下和树的直径有关的东西: 求树的直径 从树的任意 ...
- 《Cracking the Coding Interview》——第9章:递归和动态规划——题目11
2014-03-21 20:20 题目:给定一个只包含‘0’.‘1’.‘|’.‘&’.‘^’的布尔表达式,和一个期望的结果(0或者1).如果允许你用自由地给这个表达式加括号来控制运算的顺序,问 ...