懒得复制,戳我戳我

Solution:

  • 还是一个\(Splay\),我们只用多存一个值\(rad\)来维护二叉树,然后用数组存下每个书对应的值是多少
  • \(Top\)操作,我是把\(s\)旋转到根节点,然后删除,将\(s\)对应的\(rad\)值调至最小,然后插入就可以
  • \(Bottom\)操作,就是和\(Top\)相反,删除后把\(rad\)调整至最大,然后插入
  • \(Insert\)操作,\(s==0\)不用操作,\(-1\)时,就只用把\(s\)旋转到根节点,把左子树最大值旋转至左子树根节点,然后交换两个节点信息,并且交换数组储存的每个书对应的\(rad\),\(1\)就是相反的旋转右子树最小值就可以
  • \(Ask\)操作,就只用把\(s\)旋转到根节点,输出左子树大小
  • \(Query\)操作,就是找第\(s\)大的\(rad\)值对应的书籍编号就可以了
  • 一开始想怎么找编号好久,发现编号是\(1-n\)就好操作了

Code:

//It is coded by Ning_Mew on 4.12
#include<bits/stdc++.h>
#define ls(x) node[x].ch[0]
#define rs(x) node[x].ch[1]
#define fa(x) node[x].fa
#define root node[0].ch[1]
using namespace std; const int maxn=8e4+10,INF=1e9+7; int n,m,tot,vall[maxn],low=0,up=0;
struct Node{
int fa,ch[2],val,num,size;//num-> bian hao val->rand()
}node[maxn]; void update(int x){node[x].size=node[ls(x)].size+node[rs(x)].size+1;}
void connect(int x,int fa,int how){node[x].fa=fa;node[fa].ch[how]=x;}
int ident(int x){return x==node[fa(x)].ch[0]?0:1;}
void rorate(int x){
int Y=fa(x),R=fa(Y);int Yson=ident(x),Rson=ident(Y);
connect(node[x].ch[Yson^1],Y,Yson);
connect(Y,x,Yson^1);
connect(x,R,Rson);
update(Y);update(x);
}
void Splay(int x,int goal){
int to=fa(goal);
while(fa(x)!=to){
if(fa(fa(x))==to)rorate(x);
else if(ident(x)==ident(fa(x)))rorate(fa(x)),rorate(x);
else rorate(x),rorate(x);
}
}
int newnode(int x,int rad,int fa){node[++tot].val=rad;node[tot].num=x;node[tot].size=1;node[tot].fa=fa;return tot;}
void ins(int x,int rad){
//cout<<x<<' '<<rad<<endl;
int now=root;
if(!root){newnode(x,rad,0);root=tot;return;}
else{
while(1){
node[now].size++;
int nxt=rad<node[now].val?0:1;
if(!node[now].ch[nxt]){
int p=newnode(x,rad,now);
node[now].ch[nxt]=p;Splay(p,root);return;
}
now=node[now].ch[nxt];
}
}return;
}
int find(int x,int rad){
int now=root;
while(1){
if(!now)return 0;
if(node[now].val==rad){Splay(now,root);return now;}
int nxt=rad<node[now].val?0:1;
now=node[now].ch[nxt];
}
}
void del(int x,int rad,int opt,int sum){//1->del 2->swap
int pos=find(x,rad);
if(!pos)return;
if(opt==1){
if(!ls(pos)&&!rs(pos)){root=0;return;}
if(!ls(pos)){root=rs(pos);fa(root)=0;return;}
else{
int left=ls(pos);
while(rs(left))left=rs(left);
Splay(left,ls(pos));
connect(rs(pos),left,1);
connect(left,0,1);update(left);
}
}else{
if(sum==0)return;
if(sum==-1&&!ls(pos))return;
if(sum==1&&!rs(pos))return;
if(sum==-1){
int left=ls(pos);
while(rs(left))left=rs(left);
Splay(left,ls(pos));
swap(vall[ node[pos].num ],vall[ node[left].num ]);
swap(node[pos].num,node[left].num);
}else{
int right=rs(pos);
while(ls(right))right=ls(right);
Splay(right,rs(pos));
swap(vall[ node[pos].num ],vall[ node[right].num ]);
swap(node[pos].num,node[right].num);
}
}
}
int rak(int x,int rad){int pos=find(x,rad);return node[ls(pos)].size;}
int kth(int x,int rad){
int now=root;
while(1){
if(x-node[ls(now)].size==1){
Splay(now,root);return node[now].num;}
int nxt=x<=node[ls(now)].size?0:1;
if(nxt){x=x-(node[ls(now)].size+1);}
now=node[now].ch[nxt];
}
}
string s;
int main(){
scanf("%d%d",&n,&m);
int x,t;
for(int i=1;i<=n;i++){
scanf("%d",&x);
ins(x,++up);vall[x]=up;
}
//cout<<"ins finished"<<endl;
for(int i=1;i<=m;i++){
cin>>s;scanf("%d",&x);
if(s=="Top"){
del(x,vall[x],1,0);vall[x]=--low;
ins(x,vall[x]);
}
if(s=="Bottom"){
del(x,vall[x],1,0);vall[x]=++up;
ins(x,vall[x]);
}
if(s=="Insert"){
scanf("%d",&t); del(x,vall[x],2,t);
}
if(s=="Ask"){printf("%d\n",rak(x,vall[x]));}
if(s=="Query"){printf("%d\n",kth(x,vall[x]));}
}
return 0;
}

【题解】 [ZJOI2006]书架 (Splay)的更多相关文章

  1. P2596 [ZJOI2006]书架 && Splay 区间操作(三)

    P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...

  2. 洛谷 P2596 [ZJOI2006]书架 (splay)

    题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些 ...

  3. 洛谷.2596.[ZJOI2006]书架(Splay)

    题目链接 /* 五个操作: 1.将某元素置顶.删掉这个数,插入最左 2.将某元素置底.同样 3.旋到根后,直接将这个数与前驱/后继交换所有信息 不是左右子节点! 4.5.裸平衡树 ps:1.用pos[ ...

  4. BZOJ1861:[ZJOI2006]书架(Splay)

    Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下 ...

  5. [ZJOI2006]书架(权值splay)

    [ZJOI2006]书架(luogu) Description 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看 ...

  6. 「luogu2569」[ZJOI2006] 书架

    「luogu2569」[ZJOI2006]书架 题目大意 给定一个长度为 \(n\) 序列,序列中第 \(i\) 个元素有编号 \(a_i(a_i \in \Z \cap [1,n])\),需要支持五 ...

  7. 洛谷 P2596 [ZJOI2006]书架 解题报告

    P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...

  8. fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架

    题面:P2596 [ZJOI2006]书架 题解:记录每本书对应的节点编号 普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中) ...

  9. [Luogu 2596] ZJOI2006 书架

    [Luogu 2596] ZJOI2006 书架 第一次指针写 FHQ_Treap(省选噩梦数据结构)AC 啦! 省选试机写它,紧张过度失败了. 省选 Day 1 考场写它,写挂了. 省选 Day 1 ...

随机推荐

  1. Net Core 使用外部登陆提供程序登陆的流程,以及身份认证的流程

    在Asp.Net Core 中使用外部登陆(google.微博...)   原文出自Rui Figueiredo的博文<External Login Providers in ASP.NET C ...

  2. Linux SSH远程文件/文件夹传输命令scp

    相信各位VPSer在使用VPS时会常常在不同VPS间互相备份数据或者转移数据,大部分情况下VPS上都已经安装了Nginx或者类似的web server,直接将要传输的文件放到web server的文件 ...

  3. Python3入门(十)——调试与测试

    一.异常处理 1.try...except...finally... 这个也就是Java里的try...cath..finally...了,直接看经典代码: try: print("开始执行 ...

  4. Android应用安全之第三方SDK安全

    第三方sdk的包括广告.支付.统计.社交.推送,地图等类别,是广告商.支付公司.社交.推送平台,地图服务商等第三方服务公司为了便于应用开发人员使用其提供的服务而开发的工具包,封装了一些复杂的逻辑实现以 ...

  5. vs如何将工程配置,保存到属性表

    上次讲到新建一个opencv工程的配置过程,整个流程下来还是非常麻烦的.每次新建一个工程都要走这个流程的话就要疯了! 现在介绍一种将工程配置,保存到属性表的方法,那么下次新建工程时,只要添加这个属性表 ...

  6. Hadoop开发第2期---虚拟机中搭建Linux

    注:关于如何将hadoop源码导入Eclipse详见http://pan.baidu.com/s/1hq8ArUs 一.Hadoop配置软件(我的电脑是Windows7旗舰--64bit) 1. VM ...

  7. libgdx学习记录23——图片移动选择

    模拟移动选择图片,采用相机实现. package com.fxb.newtest; import com.badlogic.gdx.ApplicationAdapter; import com.bad ...

  8. ZAB协议和Paxos算法

    前言在上一篇文章Paxos算法浅析中主要介绍了Paxos一致性算法应用的场景,以及对协议本身的介绍:Google Chubby是一个分布式锁服务,其底层一致性实现就是以Paxos算法为基础的:但这篇文 ...

  9. 蓝牙学习笔记三(Android Debug)

    android 端可以通过两种方式去Debug: 一.在手机的设置功能里,开发者模式 Enable,如下图:   http://blog.bluetooth.com/debugging-bluetoo ...

  10. markdown 笔记二

    Markdown 语法笔记==============================1,头部欢迎# 欢迎使用flaskBlog ------ flask对于我来说,适合快速开发一些小网页,自己也想整 ...