Description
小T有一个很大的书柜。这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列。她用1到n的正整数给每本书都编了号。 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本。由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置。不过小T的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时的位置附近,比如说她拿的时候这本书上面有X本书,那么放回去时这本书上面就只可能有X-1、X或X+1本书。 当然也有特殊情况,比如在看书的时候突然电话响了或者有朋友来访。这时候粗心的小T会随手把书放在书柜里所有书的最上面或者最下面,然后转身离开。 久而久之,小T的书柜里的书的顺序就会越来越乱,找到特定的编号的书就变得越来越困难。于是她想请你帮她编写一个图书管理程序,处理她看书时的一些操作,以及回答她的两个提问:(1)编号为X的书在书柜的什么位置;(2)从上到下第i本书的编号是多少。
Input
第一行有两个数n,m,分别表示书的个数以及命令的条数;第二行为n个正整数:第i个数表示初始时从上至下第i个位置放置的书的编号;第三行到m+2行,每行一条命令。命令有5种形式: 1. Top S——表示把编号为S的书房在最上面。 2. Bottom S——表示把编号为S的书房在最下面。 3. Insert S T——T∈{-1,0,1},若编号为S的书上面有X本书,则这条命令表示把这本书放回去后它的上面有X+T本书; 4. Ask S——询问编号为S的书的上面目前有多少本书。 5. Query S——询问从上面数起的第S本书的编号。
Output
对于每一条Ask或Query语句你应该输出一行,一个数,代表询问的答案。
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
HINT
数据范围
#include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; struct node{ int c,d,f,id,son[2]; }tr[2100000];int len,root; int a[250000];int l,r; void update(int x) { int lc=tr[x].son[0],rc=tr[x].son[1]; tr[x].c=tr[lc].c+tr[rc].c+1; } void add(int d,int id,int f) { len++; tr[len].d=d;tr[len].f=f;tr[len].id=id;tr[len].c=1; if(d<tr[f].d)tr[f].son[0]=len; else tr[f].son[1]=len; } void rotate(int x,int w) { int f=tr[x].f,ff=tr[f].f; int r,R; r=tr[x].son[w],R=f; tr[R].son[1-w]=r; if(r!=0)tr[r].f=R; r=x,R=ff; if(tr[R].son[0]==f)tr[R].son[0]=r; else tr[R].son[1]=r; tr[r].f=R; r=f,R=x; tr[r].f=R; tr[R].son[w]=r; update(f); update(x); } void splay(int x,int rt) { while(tr[x].f!=rt) { int f=tr[x].f,ff=tr[f].f; if(ff==rt) { if(tr[f].son[0]==x)rotate(x,1); else rotate(x,0); } else { if(tr[ff].son[0]==f&&tr[f].son[0]==x){rotate(f,1);rotate(x,1);} else if(tr[ff].son[0]==f&&tr[f].son[1]==x){rotate(x,0);rotate(x,1);} else if(tr[ff].son[1]==f&&tr[f].son[0]==x){rotate(x,1);rotate(x,0);} else if(tr[ff].son[1]==f&&tr[f].son[1]==x){rotate(f,0);rotate(x,0);} } } if(rt==0)root=x; } int findip(int d) { int x=root; while(tr[x].d!=d) { if(d<tr[x].d) { if(tr[x].son[0]==0)break; x=tr[x].son[0]; } else { if(tr[x].son[1]==0)break; x=tr[x].son[1]; } } return x; } void ins(int d,int id) { if(root==0){add(d,id,0);root=len;return ;} int x=findip(d); add(d,id,x); update(x); splay(len,0); } void del(int d) { int x=findip(d);splay(x,0); if(tr[x].son[0]==0&&tr[x].son[1]==0){root=0;len=0;} else if(tr[x].son[0]==0&&tr[x].son[1]!=0){root=tr[x].son[1];tr[root].f=0;} else if(tr[x].son[0]!=0&&tr[x].son[1]==0){root=tr[x].son[0];tr[root].f=0;} else { int p=tr[x].son[0]; while(tr[p].son[1]!=0)p=tr[p].son[1]; splay(p,x); int r=tr[x].son[1],R=p; tr[R].son[1]=r; tr[r].f=R; root=R;tr[root].f=0; update(R); } } int findpaiming(int d) { int x=findip(d);splay(x,0); return tr[tr[x].son[0]].c; } int findshuzi(int k) { int x=root; while(1) { int lc=tr[x].son[0],rc=tr[x].son[1]; if(k<=tr[lc].c)x=lc; else if(k>tr[lc].c+1){k-=tr[lc].c+1;x=rc;} else break; } splay(x,0); return tr[x].id; } int findqianqu(int d) { int x=findip(d);splay(x,0); while(d<=tr[x].d&&tr[x].son[0]!=0) { x=tr[x].son[0]; while(tr[x].son[1]!=0)x=tr[x].son[1]; } if(d<=tr[x].d)x=0; return tr[x].id; } int findhouji(int d) { int x=findip(d);splay(x,0); while(d>=tr[x].d&&tr[x].son[1]!=0) { x=tr[x].son[1]; while(tr[x].son[0]!=0)x=tr[x].son[0]; } if(d>=tr[x].d)x=0; return tr[x].id; } int n,m; int main() { l=r=root=0; int nm; scanf("%d%d",&n,&m);len=0;nm=max(n,m); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); a[x]=i+nm; ins(i+nm,x); } char st[51]; while(m--) { int s,t; scanf("%s",st+1); if(st[1]==‘T‘) { scanf("%d",&s);del(a[s]); a[s]=nm-(++l); ins(a[s],s); } if(st[1]==‘B‘) { scanf("%d",&s);del(a[s]); a[s]=nm+n+(++r); ins(a[s],s); } if(st[1]==‘I‘) { scanf("%d%d",&s,&t); if(t==0)continue; if(t==1) { int x=findhouji(a[s]); del(a[x]),del(a[s]); swap(a[x],a[s]); ins(a[x],x);ins(a[s],s); } else { int x=findqianqu(a[s]); del(a[x]),del(a[s]); swap(a[x],a[s]); ins(a[x],x);ins(a[s],s); } } if(st[1]==‘A‘) { scanf("%d",&s); printf("%d\n",findpaiming(a[s])); } if(st[1]==‘Q‘) { scanf("%d",&s); printf("%d\n",findshuzi(s)); } } return 0; }
by_lmy