刷题总结——书架(bzoj1861)
题解:
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
数据范围
题解:
一道卡了我几乎一个上午的splay的模板题····
md表示insert操作脑残了·····又是删点又是加点的···导致直接t····
最后发现直接交换两者的pos和val就可以了···我tm·······
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=1e5+5; int father[N],son[N][2],val[N],size[N],root,tot,pos[N]; int n,m,a,b; char s[5]; inline int R() { char c;int f=0,i=1; for(c=getchar();(c<'0'||c>'9')&&(c!='-');c=getchar()); if(c=='-') i=-1,c=getchar(); for(;c<='9'&&c>='0';c=getchar()) f=(f<<3)+(f<<1)+c-'0'; return f*i; } inline void clear(int now) { father[now]=son[now][0]=son[now][1]=size[now]=0; } inline void update(int now) { if(now) { size[now]=1; if(son[now][0]) size[now]+=size[son[now][0]]; if(son[now][1]) size[now]+=size[son[now][1]]; } } inline int get(int now) { return son[father[now]][1]==now; } inline void rotate(int now) { int fa=father[now],ofa=father[fa],which=get(now); son[fa][which]=son[now][which^1],father[son[fa][which]]=fa; son[now][which^1]=fa,father[fa]=now,father[now]=ofa; if(ofa) son[ofa][son[ofa][1]==fa]=now; update(fa),update(now); } inline void splay(int now,int to) { while(father[now]!=to) { if(father[father[now]]!=to) rotate(get(now)==get(father[now])?father[now]:now); rotate(now); } if(!to) root=now; } inline void build(int x) { int now=root,last=0; while(true) { if(!now) { now=++tot;father[now]=last;size[now]=1;val[now]=x;pos[x]=now; if(last) son[last][1]=now;update(last); splay(now,0); break; } last=now; now=son[now][1]; } } inline int find(int x) //找到第x本的编号 { int now=root; while(true) { if(x<=size[son[now][0]]) now=son[now][0]; else { int temp=size[son[now][0]]+1; if(x==temp) {return val[now];} x-=temp;now=son[now][1]; } } } inline int pre() { int now=son[root][0]; while(son[now][1]) now=son[now][1]; return now; } inline int next() { int now=son[root][1]; while(son[now][0]) now=son[now][0]; return now; } inline void Delete(int x) //找到编号为x的书将其删除 { splay(pos[x],0); if(!son[root][0]){int oldroot=root;root=son[root][1];father[root]=0;clear(oldroot);return;} if(!son[root][1]){int oldroot=root;root=son[root][0];father[root]=0;clear(oldroot);return;} else { int leftbig=pre(),oldroot=root; splay(leftbig,0); son[root][1]=son[oldroot][1]; father[son[root][1]]=root; update(root);clear(oldroot); return; } } inline void findtop()//找到最上面的书并将其旋转至根节点 { int now=root; while(son[now][0]) now=son[now][0]; splay(now,0); } inline void findbot() { int now=root; while(son[now][1]) now=son[now][1]; splay(now,0); } inline void inserttop(int x) //把x放在书的最上面 { Delete(x);findtop(); son[root][0]=pos[x]; father[pos[x]]=root;size[pos[x]]=1;son[pos[x]][0]=son[pos[x]][1]=0; update(root); } inline void insertbot(int x) //把x放在书的最下面 { Delete(x);findbot(); son[root][1]=pos[x]; father[pos[x]]=root;size[pos[x]]=1;son[pos[x]][0]=son[pos[x]][1]=0; update(root); } int main() { //freopen("a.in","r",stdin); n=R(),m=R(); for(int i=1;i<=n;i++) a=R(),build(a); while(m--) { scanf("%s",s); if(s[0]=='T') {a=R();inserttop(a);} if(s[0]=='B') {a=R();insertbot(a);} if(s[0]=='I') { a=R(),b=R(); if(!b) continue; else { splay(pos[a],0);int temp,flag=0; if(b==0) continue; if(b==-1) temp=pre(); if(b==1) temp=next(); int t1=val[temp],t2=pos[a]; swap(pos[t1],pos[a]); swap(val[t2],val[temp]); } } if(s[0]=='A') { a=R();splay(pos[a],0); if(!son[root][0]) cout<<"0"<<endl; else cout<<size[son[root][0]]<<endl; } if(s[0]=='Q') a=R(),cout<<find(a)<<endl; } return 0; }