[省选前衡八题目整理][BZOJ 1503]郁闷的出纳员(Splay)
2015-03-23 18:38
405 查看
题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=1503思路
嘴巴一下还是很简单的,就是个很裸的数据结构题,要求能够支持删除、加入结点以及查询第k大数。当然Treap和Splay都能做的啦。。。。记得我第一次做是用Treap过的
但是还是有很多细节要注意的,刚开始写完过了样例就交了,没想到居然WA,后来随手在查询完第k大数时把第k大数splay到根节点上去,发现这样做就过不了样例,调了一下午发现是插入结点o时,由于是&o,而插入完结点o后要做splay操作,o的值会发生变化,而最后要给o做pushup操作,因此要先用一个变量tmpo记录下o原来的值,pushup原来的结点o。。。。
代码
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #define MAXN 210000 using namespace std; int val[MAXN],ch[MAXN][2],fa[MAXN],size[MAXN]; int nCount=0,root=0; int limit; //工资下限 int sum=0; //sum=离开公司的员工总数 void pushup(int o) { size[o]=size[ch[o][0]]+size[ch[o][1]]+1; } void rot(int x,int &k) { int y=fa[x],z=fa[y]; int p,q; if(ch[y][0]==x) p=0; //!!!!! else p=1; q=p^1; if(y!=k) { if(ch[z][0]==y) ch[z][0]=x; else ch[z][1]=x; } else k=x; fa[y]=x,fa[x]=z; ch[y][p]=ch[x][q]; fa[ch[x][q]]=y; ch[x][q]=y; pushup(y); pushup(x); } void splay(int x,int &k) { while(x!=k) { int y=fa[x],z=fa[y]; if(y!=k) { if((ch[y][0]==x)==(ch[z][0]==y)) rot(y,k); else rot(x,k); } rot(x,k); } } void ins(int &o,int father,int v) { int tmpo=o; //!!!!!o是会改变的!!!!要用个tmpo记住原来的o是哪个点 if(!o) { o=++nCount; ch[o][0]=ch[o][1]=0; fa[o]=father; val[o]=v; size[o]=1; splay(o,root); return; } if(v<val[o]) ins(ch[o][0],o,v); else ins(ch[o][1],o,v); pushup(tmpo); } void del(int &o,int father) { if(!o) return; if(val[o]>=limit) del(ch[o][0],o); else { sum+=size[ch[o][0]]+1; //!!!!! o=ch[o][1]; //o和其左子树全部被删了 fa[o]=father; //if(!father) root=o; del(o,father); } if(o) pushup(o); } int findKth(int o,int k) { if(!o) return -1; if(size[ch[o][0]]+1==k) { splay(o,root); return o; } if(size[ch[o][0]]>=k) return findKth(ch[o][0],k); //!!!!!! return findKth(ch[o][1],k-size[ch[o][0]]-1); } int main() { int q,m,w=0; //w=所有员工加上的工资大小 scanf("%d%d",&q,&m); char cmd[10]; while(q--) { int k; scanf("%s%d",cmd,&k); if(cmd[0]=='I') { if(k<m) continue; //!!!!!! ins(root,0,k-w); } else if(cmd[0]=='A') w+=k; else if(cmd[0]=='S') { w-=k; limit=m-w; del(root,0); } else { int tmp=size[root]; if(tmp<k) { printf("-1\n"); continue; } printf("%d\n",val[findKth(root,tmp-k+1)]+w); } } printf("%d\n",sum); return 0; }
相关文章推荐
- BZOJ 1503 郁闷的出纳员 二叉平衡树(Treap,Splay)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- BZOJ 1503 [NOI2004]郁闷的出纳员 (splay)
- 【bzoj1503】[NOI2004]郁闷的出纳员 Splay
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- [BZOJ1503]NOI2004 郁闷的出纳员|splay
- 【codevs1286】【BZOJ1503】郁闷的出纳员,splay练习
- Bzoj 1503: [NOI2004]郁闷的出纳员(splay)
- 【splay】BZOJ 1503 郁闷的出纳员
- _bzoj1503 [NOI2004]郁闷的出纳员【Splay】
- 【BZOJ】1503: [NOI2004]郁闷的出纳员(Splay)
- [bzoj1503][NOI2004]郁闷的出纳员——splay
- bzoj 1503: [NOI2004]郁闷的出纳员 splay
- bzoj1503郁闷的出纳员 Splay
- bzoj 1503: [NOI2004]郁闷的出纳员 splay
- 郁闷的出纳员 bzoj 1503 splay
- BZOJ 1503: [NOI2004]郁闷的出纳员 splay
- bzoj1503 [NOI2004]郁闷的出纳员 splay
- bzoj1503 [NOI2004]郁闷的出纳员(splay)
- BZOJ 1503 郁闷的出纳员(splay)