题目链接

  通过这题我加深了对Splay的理解,原来Splay的子树也是可以接来接去接到别的点上的,而不是只能旋转qwq

  具体接的办法就是swap大法。

  对于Top操作我们把当前节点Splay到根,然后把它的左子树接到后继上。

  Bottom同理

  对于Insert,暴力swap当前节点和它的前驱或者后继。

  Ask操作就把节点Splay到根,然后输出它的左子树有多少节点。

  Query直接查就行。

  

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cstdlib>
#define maxn 1000010
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} int pos[maxn];
int CNT=;
struct Splay{
struct Node{
int key,val,fa,e[],size;
}tree[maxn];
int tag[maxn];
int point,tot,root;
Splay(){point=tot=root=;memset(tag,,sizeof(tag)); }
inline void update(int x){ tree[x].size=tree[tree[x].e[]].size+tree[tree[x].e[]].size+; }
inline void connect(int x,int fa,int how){ tree[x].fa=fa; tree[fa].e[how]=x; }
inline int iden(int x){ return x==tree[tree[x].fa].e[]; }
inline void rotate(int x){
int y=tree[x].fa;int r=tree[y].fa;
if(y==root) root=x;
int sony=iden(x);int sonr=iden(y);
int b=tree[x].e[sony^];
connect(b,y,sony);
connect(y,x,sony^);
connect(x,r,sonr);
update(y); update(x);
}
void splay(int pos,int to){
to=tree[to].fa;
while(tree[pos].fa!=to){
if(tree[tree[pos].fa].fa==to) rotate(pos);
else
if(iden(pos)==iden(tree[pos].fa)){
rotate(tree[pos].fa);
rotate(pos);
}
else{ rotate(pos); rotate(pos); }
}
}
int create(int key,int val,int fa){
tree[++tot].val=val; tree[tot].fa=fa;
tree[tot].size=; tree[tot].key=key;
return tot;
}
int build(int key,int val){
if(root==){ root=create(key,val,); return root; }
int now=root;
while(){
tree[now].size++;
int nxt=tree[now].key>key?:;
if(tree[now].e[nxt]==){
connect(create(key,val,now),now,nxt);
return tot;
}
now=tree[now].e[nxt];
}
}
void insert(int key,int val){
int p=build(key,val);
pos[val]=p;
if(++CNT=){
CNT=;
splay(p,root);
}
}
int find(int rnk){
int now=root;
while(now){
if(tree[tree[now].e[]].size+==rnk) return now;
else if(tree[tree[now].e[]].size>=rnk) now=tree[now].e[];
else{
rnk-=tree[tree[now].e[]].size+;
now=tree[now].e[];
}
}
}
void rotop(int val){
val=pos[val];
splay(val,root);
int le=tree[val].e[];
if(le==) return;
if(tree[val].e[]==){
connect(le,val,);
tree[val].e[]=;
update(val);
}
else{
int deal=find(tree[tree[val].e[]].size+);
connect(tree[val].e[],deal,); tree[val].e[]=;
int now=deal;
while(now){
update(now);
now=tree[now].fa;
}
splay(deal,root);
}
}
void roend(int val){
val=pos[val];
splay(val,root);
int ri=tree[val].e[];
if(ri==) return;
if(tree[val].e[]==){
connect(ri,val,);
tree[val].e[]=;
update(val);
}
else{
int deal=find(tree[tree[val].e[]].size);
connect(tree[val].e[],deal,); tree[val].e[]=;
int now=deal;
while(now){
update(now);
now=tree[now].fa;
}
splay(deal,root);
}
}
void rofro(int val){
val=pos[val];
splay(val,root);
int deal=find(tree[tree[val].e[]].size);
std::swap(pos[tree[val].val],pos[tree[deal].val]);
std::swap(tree[val].val,tree[deal].val);
}
void rosub(int val){
val=pos[val];
splay(val,root);
int deal=find(tree[tree[val].e[]].size+);
std::swap(pos[tree[val].val],pos[tree[deal].val]);
std::swap(tree[val].val,tree[deal].val);
}
int rank(int key){
int now=root;
while(now){
if(tree[tree[now].e[]].size+==key) return tree[now].val;
if(tree[tree[now].e[]].size>=key) now=tree[now].e[];
else{
key-=tree[tree[now].e[]].size+;
now=tree[now].e[];
}
}
return ;
}
int arank(int val){
val=pos[val];
splay(val,root);
return tree[tree[val].e[]].size;
}
}s; int main(){
int n=read(),m=read();
for(int i=;i<=n;++i){
int x=read();
s.insert(i,x);
}
for(int i=;i<=m;++i){
char c[];int x;
scanf("%s%d",c,&x);
switch(c[]){
case 'T':{
s.rotop(x);
break;
}
case 'B':{
s.roend(x);
break;
}
case 'I':{
int y=read();
if(y==-) s.rofro(x);
if(y==) s.rosub(x);
break;
}
case 'A':{
printf("%d\n",s.arank(x));
break;
}
case 'Q':{
printf("%d\n",s.rank(x));
break;
}
}
}
return ;
}

【Luogu】P2596书架(Splay)的更多相关文章

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

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

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

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

  3. luogu P2596 [ZJOI2006]书架

    传送门 感觉要死在\(Splay\)里了 orz 这题用\(Splay\)维护这个序列,其中的第\(k\)大点代表这个序列的第\(k\)个数 第一个操作,先把那个数所在的点旋到根,然后把整个根的左子树 ...

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

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

  5. BZOJ 1861: [Zjoi2006]Book 书架 splay

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

  6. BZOJ-1861 Book 书架 Splay

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 1010 Solved: 588 [Submit][Stat ...

  7. [题解]bzoj 1861 Book 书架 - Splay

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1396  Solved: 803[Submit][Stat ...

  8. [LSGDOJ1822]书架 Splay

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

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

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

随机推荐

  1. 使用脚本在Linux服务器上自动安装Kubernetes的包管理器Helm

    Helm之于Kubernetes好比yum之于Red Hat Enterprise Linux,或者apt-get之于Ubuntu. Helm是由helm CLI和Tiller组成,是典型的Clien ...

  2. 用代码判断当前系统是否支持某个版本的feature

    JDK9已经出来有一段时间了,因此很多流行的Java应用纷纷增添了对JDK9乃至JDK10的支持,比如Tomcat. 我们通过这个链接下载最新的Tomcat源文件包,总共7MB: https://to ...

  3. 01_7_cookies

    01_7_cookies 1. cookies 1.1服务器可以向客户端写内容 1.2只能是文本内容 1.3客户端可以阻止服务器写入 1.4只能拿到自己webapp写入的东西 1.5Cookie分为两 ...

  4. NOIP2016——大家一起实现の物语

    由于最近硬盘挂了,换了个固态硬盘,比赛结束后四天一直在装Linux,所以最近一直没怎么更新 看起来挺漂亮的 比赛前一个月申请停了一个月晚自习,在我们这座城市里能做到这种事情已经可以被称为奇迹了,并且在 ...

  5. Python + Bottle + 谷歌搜索Api 实现简单搜索引擎

    1.运行环境 python3 centos7 2.Bottle的使用 使用bottle主要是因为它仅用python自带的库即可实现对web的搭建. bottle源码分析 bottle使用教程 3.代码 ...

  6. MySQL中文转换成拼音的函数

    CREATE DEFINER=`root`@`localhost` FUNCTION `fristPinyin`(`P_NAME` VARCHAR(255) CHARSET utf8) RETURNS ...

  7. laravel5 使用try catch

    在laravel5中使用以下代码并没有捕获异常 try{ var_dump($val); }catch (Exception $e){ var_dump($e); }  Laravel 5 时代控制器 ...

  8. OpenCV编译 Make出错 recipe for target 'modules/imgproc/CMakeFiles/opencv_test_imgproc.dir/all' failed

    OpenCV编译  Make出错 recipe for target 'modules/imgproc/CMakeFiles/opencv_test_imgproc.dir/all' failed 添 ...

  9. Linux系统入门-Bash初识

    目录 Linux系统入门-Bash初识 Bash Shell介绍 Bash Shell的作用 Bash的两种使用方式 命令提示符 shell的基础语法 shell的基本特性 命令补全 linux快捷键 ...

  10. Python基础——判断和循环

    判断 缩进代替大括号. 冒号(:)后换号缩进. if test=100 if test>50: print('OK') print('test') if-elif-else test=50 if ...