1861: [Zjoi2006]Book 书架
来源:互联网 发布:九仙图仙羽进阶数据 编辑:程序博客网 时间:2024/05/02 01:20
1861: [Zjoi2006]Book 书架
Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1822 Solved: 1038
[Submit][Status][Discuss]
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
数据范围
Source
Day2
这一道题卡了五天!!!!!!
#include<cstring>#include<cstdio>#include<algorithm>using namespace std;#define MAXN 100000struct Spaly{ int ch[MAXN][2],f[MAXN],size[MAXN],cnt[MAXN],key[MAXN],rank[MAXN],val[MAXN]; int sz,root; void init() { sz=root=0; } inline void clear(int x) { ch[x][0]=ch[x][1]=f[x]=size[x]=cnt[x]=key[x]=0; } inline bool get(int x) { return ch[f[x]][1]==x; } inline void update(int x) { if (x) { size[x]=cnt[x]; if (ch[x][0]) size[x]+=size[ch[x][0]]; if (ch[x][1]) size[x]+=size[ch[x][1]]; } } inline void rotate(int x) { int old=f[x],oldf=f[old],whichx=get(x); ch[old][whichx]=ch[x][whichx^1]; f[ch[old][whichx]]=old; ch[x][whichx^1]=old; f[old]=x; f[x]=oldf; if (oldf) ch[oldf][ch[oldf][1]==old]=x; update(old); update(x); } inline void splay(int x) { for (int fa; fa=f[x]; rotate(x)) if (f[fa]) rotate((get(x)==get(fa))?fa:x); root=x; } inline void insert(int x) { if (root==0) { sz++; ch[sz][0]=ch[sz][1]=f[sz]=0; root=sz; size[sz]=cnt[sz]=1; key[sz]=x; return; } int now=root,fa=0; while(1) { if (x==key[now]) { cnt[now]++; update(now); update(fa); splay(now); break; } fa=now; now=ch[now][key[now]<x]; if (now==0) { sz++; ch[sz][0]=ch[sz][1]=0; f[sz]=fa; size[sz]=cnt[sz]=1; ch[fa][key[fa]<x]=sz; key[sz]=x; update(fa); splay(sz); break; } } } inline int find(int x)///x是第几名 { int now=root,ans=0; while(1) { if (x<key[now]) now=ch[now][0]; else { ans+=(ch[now][0]?size[ch[now][0]]:0); if (x==key[now]) { splay(now); return ans+1; } ans+=cnt[now]; now=ch[now][1]; } } } inline int findx(int x)///第x名是谁 { int now=root; while(1) { if (ch[now][0]&&x<=size[ch[now][0]]) now=ch[now][0]; else { int temp=(ch[now][0]?size[ch[now][0]]:0)+cnt[now]; if (x<=temp) return key[now]; x-=temp; now=ch[now][1]; } } } inline int pre() { int now=ch[root][0]; while (ch[now][1]) now=ch[now][1]; return now; } inline int next() { int now=ch[root][1]; while (ch[now][0]) now=ch[now][0]; return now; } inline void del(int x) { int whatever=find(x); if (cnt[root]>1) { cnt[root]--; update(root); return; } if (!ch[root][0]&&!ch[root][1]) { clear(root); root=0; return; } if (!ch[root][0]) { int oldroot=root; root=ch[root][1]; f[root]=0; clear(oldroot); return; } else if (!ch[root][1]) { int oldroot=root; root=ch[root][0]; f[root]=0; clear(oldroot); return; } int leftbig=pre(),oldroot=root; splay(leftbig); ch[root][1]=ch[oldroot][1]; f[ch[oldroot][1]]=root; clear(oldroot); update(root); }} sp;int main(){ int n,m; char op[50]; while(scanf("%d%d",&n,&m)!=EOF) { sp.init(); for(int i=1; i<=n; i++) { int tmp; scanf("%d",&tmp); sp.rank[tmp]=i; sp.val[i]=tmp; sp.insert(i); } while(m--) { int cho,ch; scanf("%s %d",op,&ch); switch(op[0]) { case 'T': { sp.splay(ch=sp.rank[ch]); int left=sp.ch[sp.root][0]; if(left==0) break; if(sp.ch[sp.root][1]==0) { sp.ch[sp.root][0]=0; sp.ch[sp.root][1]=left; break; } int pos=sp.next(); sp.ch[pos][0]=left; sp.f[left]=pos; sp.ch[sp.root][0]=0; sp.splay(left); } break; case 'B': { sp.splay(ch=sp.rank[ch]); int right=sp.ch[sp.root][1]; if(right==0) break; if(sp.ch[sp.root][0]==0) { sp.ch[sp.root][1]=0; sp.ch[sp.root][0]=right; break; } int pos=sp.pre(); sp.ch[pos][1]=right; sp.f[right]=pos; sp.ch[sp.root][1]=0; sp.splay(right); } break; case 'A': { sp.splay(sp.rank[ch]); printf("%d\n",sp.size[sp.ch[sp.root][0]]); } break; case 'I': { scanf("%d",&cho); if(cho==0) break; int s; sp.splay(s=sp.rank[ch]); int pre=sp.pre(); int net=sp.next(); if(cho==1)///右边 { swap(sp.rank[ch],sp.rank[sp.val[net]]); swap(sp.val[s],sp.val[net]); } else { swap(sp.rank[ch],sp.rank[sp.val[pre]]); swap(sp.val[s],sp.val[pre]); } } break; case 'Q': { printf("%d\n",sp.val[sp.findx(ch)]); } break; } } } return 0;}
- 1861: [Zjoi2006]Book 书架
- 1861: [Zjoi2006]Book 书架
- 1861: [Zjoi2006]Book 书架
- BZOJ 1861: [Zjoi2006]Book 书架
- 【BZOJ 1861】 [Zjoi2006]Book 书架
- bzoj 1861: [Zjoi2006]Book 书架
- BZOJ 1861 [Zjoi2006] Book 书架
- BZOJ 1861 [Zjoi2006]Book 书架
- bzoj 1861 [Zjoi2006]Book 书架
- BZOJ 1861 ZJOI2006 Book 书架 Splay
- 【BZOJ 1861】[Zjoi2006]Book 书架 splay
- Book 书架 Zjoi2006
- [BZOJ1861][Zjoi2006]Book 书架
- [BZOJ1861] [Zjoi2006]Book 书架
- bzoj1861: [Zjoi2006]Book 书架
- BZOJ1861: [Zjoi2006]Book 书架
- bzoj1861: [Zjoi2006]Book 书架
- bzoj1861: [Zjoi2006]Book 书架
- dddhhhfff
- PCI总线基础知识和SylixOS下PCI设备驱动框架介绍
- 射频微波仪器
- angularjs路由小项目
- 小朋友学C语言(23):二进制与十进制之间的转换
- 1861: [Zjoi2006]Book 书架
- 小朋友学C语言(24):位运算符
- 我的CSDN博客开通啦
- [队内测试Day10.24Final]逆序对+表达式计算+贪心+图论+数论?
- OKHtt自己封装
- 小朋友学C语言(25):两数交换
- java_se 内部类-成员内部类
- 调用系统相机
- 小朋友学C语言(26):冒泡排序