题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1861
题意:一个n个数字的数列,数字两两不同。5种操作:(1) 将某个数字调整到第一个位置;(2)将某个数字调整到最后一个位置;(3)将某个数字向前、向后调整一个位置;(4)询问某个数字在数列中的位置;(5)询问数列中某个位置的数字。
思路:使用map映射某个数字与其所在数组的地址。其他的就是简单的splay。
struct node
{
int size,s;
node *c[2],*f;
};
int n,m;
int d[N];
map<int,node*> mp;
node a[N],*nullNode,*root;
int e;
void pushUp(node *x)
{
if(x==nullNode) return;
x->size=x->c[0]->size+1+x->c[1]->size;
}
void zig(node *x)
{
node *p=x->f,*q=p->f;
p->c[0]=x->c[1];
if(x->c[1]!=nullNode) x->c[1]->f=p;
x->c[1]=p;
p->f=x;
x->f=q;
if(q!=nullNode)
{
if(q->c[0]==p) q->c[0]=x;
else q->c[1]=x;
}
pushUp(p);
pushUp(x);
if(root==p) root=x;
}
void zag(node *x)
{
node *p=x->f,*q=p->f;
p->c[1]=x->c[0];
if(x->c[0]!=nullNode) x->c[0]->f=p;
x->c[0]=p;
p->f=x;
x->f=q;
if(q!=nullNode)
{
if(q->c[0]==p) q->c[0]=x;
else q->c[1]=x;
}
pushUp(p);
pushUp(x);
if(root==p) root=x;
}
void splay(node *x,node *goal)
{
while(x->f!=goal)
{
if(x->f->f!=goal)
{
if(x->f->f->c[0]==x->f)
{
if(x->f->c[0]==x) zig(x->f),zig(x);
else zag(x),zig(x);
}
else
{
if(x->f->c[1]==x) zag(x->f),zag(x);
else zig(x),zag(x);
}
}
else
{
if(x->f->c[0]==x) zig(x);
else zag(x);
}
}
}
void select(int k,node *goal)
{
node *x=root;
while(x->c[0]->size+1!=k)
{
if(x->c[0]->size>=k) x=x->c[0];
else
{
k-=1+x->c[0]->size;
x=x->c[1];
}
}
splay(x,goal);
}
int select1(int k)
{
node *x=root;
while(x->c[0]->size+1!=k)
{
if(x->c[0]->size>=k) x=x->c[0];
else
{
k-=1+x->c[0]->size;
x=x->c[1];
}
}
return x->s;
}
node* newNode(int s,node *f)
{
node *p=&a[++e];
p->c[0]=p->c[1]=nullNode;
p->f=f;
p->s=s;
p->size=1;
mp[s]=p;
return p;
}
void init()
{
nullNode=new node();
nullNode->c[0]=nullNode->c[1]=nullNode->f=nullNode;
nullNode->size=0;
root=newNode(0,nullNode);
root->c[1]=newNode(0,root);
pushUp(root);
}
node *build(int L,int R,node *f)
{
int M=(L+R)>>1;
node *p=newNode(d[M],f);
if(L<M) p->c[0]=build(L,M-1,p);
if(M<R) p->c[1]=build(M+1,R,p);
pushUp(p);
return p;
}
void del(node* p)
{
splay(p,nullNode);
int L=p->c[0]->size;
select(L,nullNode);
select(L+2,root);
root->c[1]->c[0]=nullNode;
splay(root->c[1],nullNode);
}
void insert(int pos,node *p)
{
select(pos,nullNode);
select(pos+1,root);
root->c[1]->c[0]=p;
p->f=root->c[1];
splay(p,nullNode);
}
void top(int s)
{
node *p=mp[s];
del(p);
p=newNode(s,nullNode);
insert(1,p);
}
void bottom(int s)
{
node *p=mp[s];
del(p);
p=newNode(s,nullNode);
insert(n,p);
}
void insert(int S,int T)
{
if(T==0) return;
node *p=mp[S];
splay(p,nullNode);
int size=p->c[0]->size;
del(p);
p=newNode(S,nullNode);
if(T==-1) insert(size-1,p);
else insert(size+2-1,p);
}
int ask(int s)
{
node *p=mp[s];
splay(p,nullNode);
return p->c[0]->size-1;
}
int query(int s)
{
return select1(s+1);
}
void go()
{
char op[20];
int S,T;
while(m--)
{
RD(op); RD(S);
if(op[0]=='T') top(S);
else if(op[0]=='B') bottom(S);
else if(op[0]=='I') RD(T),insert(S,T);
else if(op[0]=='A') PR(ask(S));
else PR(query(S));
}
}
int main()
{
RD(n,m);
int i;
FOR1(i,n) RD(d[i]);
init();
node *p=build(1,n,root->c[1]);
root->c[1]->c[0]=p;
splay(p,nullNode);
go();
}