正题
书架可以放书
其实这道题非常裸,就是只有放到头,放到尾,与前驱或者和后继交换。
那么splay就可以完成这个操作。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int n,m;
int a[80010];
struct node{
int num,son[2],f,t;
}s[80010];
int image[80010];
int tot=0;
int root=0;
void update(int x){
s[x].t=s[s[x].son[0]].t+s[s[x].son[1]].t+1;
}
void rotate(int x,int w){
int f=s[x].f,ff=s[f].f;
s[f].son[1-w]=s[x].son[w];
if(s[x].son[w]!=0) s[s[x].son[w]].f=f;
if(s[ff].son[1]==f) s[ff].son[1]=x;
else s[ff].son[0]=x;
s[x].f=ff;
s[x].son[w]=f;
s[f].f=x;
update(f);
update(x);
}
void splay(int x,int tar){
while(s[x].f!=tar){
int f=s[x].f,ff=s[f].f;
if(ff==tar) {
if(s[f].son[0]==x) rotate(x,1);
else rotate(x,0);
}
else{
if(s[ff].son[0]==f){
if(s[f].son[0]==x) {rotate(f,1);rotate(x,1);}
else {rotate(x,0);rotate(x,1);}
}
else{
if(s[f].son[0]==x) {rotate(x,1);rotate(x,0);}
else {rotate(f,0);rotate(x,0);}
}
}
}
if(tar==0) root=x;
}
void build(int x,int y){//二分建树会使后面的操作更快
tot++;
int i=tot;
int mid=(x+y)/2;
s[i].son[0]=s[i].son[1]=0;
s[i].num=a[mid];
image[a[mid]]=i;
if(x<mid){
s[i].son[0]=tot+1;
s[tot+1].f=i;
build(x,mid-1);
}
if(mid<y){
s[i].son[1]=tot+1;
s[tot+1].f=i;
build(mid+1,y);
}
update(i);
}
void del(int x){//删除该节点
splay(x,0);
if(s[x].son[0]==0 && s[x].son[1]!=0) {root=s[x].son[1];s[s[x].son[1]].f=0;}
else if(s[x].son[0]!=0 && s[x].son[1]==0) {root=s[x].son[0];s[s[x].son[0]].f=0;}
else{
int now=s[x].son[0];
while(s[now].son[1]!=0) now=s[now].son[1];
splay(now,x);
s[now].son[1]=s[x].son[1];
s[s[x].son[1]].f=now;s[now].f=0;
root=now;
update(now);
}
s[x].son[0]=s[x].son[1]=0;
update(x);
}
void to_top(int w,int x){//放到最前面和放到最后面,w为0时放到最前面,w为1时放到最后面。
int now=root;
while(s[now].son[w]!=0) now=s[now].son[w];
s[now].son[w]=x;
s[x].f=now;
update(x);
now=x;
while(s[now].f!=0) {now=s[now].f;update(now);}
return ;
}
void push_top(int x){//删掉在放到最前面
if(n==1) return ;
del(x);
to_top(0,x);
}
void push_bottom(int x){//删掉在放到最后面
if(n==1) return ;
del(x);
to_top(1,x);
}
void insert(int x,int w){//插入一本书,即与前驱后继交换
if(w==0) return ;
if(w==-1) w=0;
splay(x,0);
int now=s[root].son[w];
while(s[now].son[1-w]!=0) now=s[now].son[1-w];
del(x);
splay(now,0);
s[x].son[w]=s[now].son[w];
s[now].son[w]=x;s[x].f=now;
s[s[x].son[w]].f=x;
update(x);
update(now);
}
int ask(int x){
splay(x,0);
return s[s[x].son[0]].t;
}
int query(int x){
int now=root;
while(1){
if(x<=s[s[now].son[0]].t) now=s[now].son[0];
else if(x>s[s[now].son[0]].t+1) x-=s[s[now].son[0]].t+1,now=s[now].son[1];
else break;
}
return s[now].num;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,n);
char c[20];
int x,w;
root=1;
for(int i=1;i<=m;i++){
scanf("%s",c);
scanf("%d",&x);/*
for(int i=1;i<=n;i++)
printf("%d ",s[image[i]].t);
printf("\n");*/
if(c[0]=='I') scanf("%d",&w);
if(c[0]=='T') push_top(image[x]);
else if(c[0]=='B') push_bottom(image[x]);
else if(c[0]=='I') insert(image[x],w);
else if(c[0]=='A') printf("%d\n",ask(image[x]));
else if(c[0]=='Q') printf("%d\n",query(x));
}
}