luoguP2596 [ZJOI2006]书架(splay)
来源:互联网 发布:vb中四舍五入取整函数 编辑:程序博客网 时间:2024/05/22 00:36
题目链接
分析:
第一次看这道题的时候,按照数组中的顺序建立splay
但是一时脑抽,想不到怎么查找编号为S的书在哪个结点
过了大约一周,又来看这道题,发现一周之前的我是那么的simple&naive
在splay中,我们无论怎么splay||rotate,每个结点内包含的信息是不会变得,变动的只有结点之间的关系
也就是说,我们只要用一个数组pos,记录一下每个编号在splay中位于哪个结点
我们在删除结点的时候,不要用clear,而是继续使用这个结点(不重新申请结点,注意ch,pre,sz的信息要初始化)
这样就可以解决给出编号的询问了
tip
于是写完了之后,交上去:70
这是怎么回事呐?
注意我对于insert的定义:
当遇到Bottom等操作的时候,在ta上面有n-1本书
//这里写代码片#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int N=80010;int v[N],ch[N][2],sz[N],pre[N];int n,m,a[N],root,top=0,pos[N];int get(int bh){ return ch[pre[bh]][0]==bh ? 0:1;}void update(int bh){ if (!bh) return; sz[bh]=1; if (ch[bh][0]) sz[bh]+=sz[ch[bh][0]]; if (ch[bh][1]) sz[bh]+=sz[ch[bh][1]];}void rotate(int bh){ int fa=pre[bh]; int grand=pre[fa]; int wh=get(bh); ch[fa][wh]=ch[bh][wh^1]; pre[ch[fa][wh]]=fa; ch[bh][wh^1]=fa; pre[fa]=bh; pre[bh]=grand; if (grand) ch[grand][ch[grand][0]==fa ? 0:1]=bh; update(fa); update(bh);}void splay(int bh,int mb){ for (int fa;(fa=pre[bh])!=mb;rotate(bh)) if (pre[fa]!=mb) rotate(get(bh)==get(fa)? fa:bh); if (!mb) root=bh;}int build(int l,int r,int fa){ if (l>r) return 0; int mid=(l+r)>>1; int now=++top; ch[now][0]=build(l,mid-1,now); ch[now][1]=build(mid+1,r,now); v[now]=a[mid]; pre[now]=fa; update(now); return now;}int find(int x) //排名为x的结点编号 { int now=root; while (1) { if (ch[now][0]&&sz[ch[now][0]]>=x) now=ch[now][0]; else { int tmp=(ch[now][0]? sz[ch[now][0]]:0); tmp++; if (x<=tmp) return now; x-=tmp; now=ch[now][1]; } }}int fro(){ int now=ch[root][0]; while (ch[now][1]) now=ch[now][1]; return now;}int nxt(){ int now=ch[root][1]; while (ch[now][0]) now=ch[now][0]; return now;}void insert(int x,int p) //上面有x本书,当前插入的是p结点 { if (x==0) { splay(find(x),0); ch[root][0]=p; pre[p]=root; update(root); return; } if (x==n-1) { splay(find(x),0); ch[root][1]=p; pre[p]=root; update(root); return; } splay(find(x),0); int ls=nxt(); splay(ls,root); ch[ls][0]=p; pre[p]=ls; update(ls); update(root);}void del() //删除根结点 { if (!ch[root][0]&&!ch[root][1]) { root=0; return; } if (!ch[root][0]) { root=ch[root][1]; pre[root]=0; return; } if (!ch[root][1]) { root=ch[root][0]; pre[root]=0; return; } int k=root; int pr=fro(); splay(pr,0); ch[root][1]=ch[k][1]; pre[ch[k][1]]=root; update(root); return;}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); root=build(1,n,0); for (int i=1;i<=n;i++) pos[v[i]]=i; char s[10]; int S,T; for (int i=1;i<=m;i++) { scanf("%s",s); scanf("%d",&S); if (s[0]=='T') { int num=pos[S]; //在splay中的编号 splay(num,0); del(); sz[num]=1; ch[num][0]=ch[num][1]=pre[num]=0; insert(0,num); } else if (s[0]=='B') { int num=pos[S]; splay(num,0); del(); sz[num]=1; ch[num][0]=ch[num][1]=pre[num]=0; insert(n-1,num); } else if (s[0]=='I') { scanf("%d",&T); if (T==0) continue; int num=pos[S]; splay(num,0); int sum=sz[ch[root][0]]; del(); sz[num]=1; ch[num][0]=ch[num][1]=pre[num]=0; insert(sum+T,num); } else if (s[0]=='A') { splay(pos[S],0); printf("%d\n",sz[ch[root][0]]); } else { printf("%d\n",v[find(S)]); } } return 0;}
阅读全文
0 0
- luoguP2596 [ZJOI2006]书架(splay)
- [BZOJ1861][ZJOI2006]书架(平衡树splay)
- [ZJOI2006书架]Splay
- [BZOJ1861][Zjoi2006]Book 书架 && splay
- 【BZOJ1861】【Zjoi2006】Book 书架 Splay
- 【bzoj1861】[Zjoi2006]Book 书架 splay
- BZOJ1861: [Zjoi2006]Book 书架 Splay
- [bzoj1861][Zjoi2006]Book书架 splay
- BZOJ 1861 ZJOI2006 Book 书架 Splay
- 【BZOJ 1861】[Zjoi2006]Book 书架 splay
- splay伸展树基础操作(bzoj 1861: [Zjoi2006]Book 书架)
- splay学习小结1.1【BZOJ 1861】[Zjoi2006]Book 书架
- 【BZOJ1861】书架(Splay)
- 【ZJOI2006】书架
- [ZJOI2006] 书架
- 洛谷P2596 [ZJOI2006]书架(BZOJ1861)
- BZOJ 1861 书架(splay)
- Book 书架 Zjoi2006
- JavaWeb之过滤器实现统一编码案例
- 刷新购物车的操作以及创建订单
- 初窥ajax(二) ——封装jsonp
- 跟着鱼C学HTML学习记录0
- MappingJackson2HttpMessageConverter(undone)
- luoguP2596 [ZJOI2006]书架(splay)
- 蓝桥杯 ADV_193 算法提高 新建Microsoft Word文档 (java)
- 数据结构实验之排序二:交换排序
- 服务器主动向客户端发送信息机制
- HDOJ 2032 杨辉三角
- 基于stanford nlp(JAVA)实现关系抽取
- 【中文字幕】2017春季CS231n 斯坦福深度视觉识别课,李飞飞
- reason: connect ETIMEDOUT
- 根据log绘制loss、accuracy的变化图