(题解)(Splay)NOI2004郁闷的出纳员
来源:互联网 发布:js内置对象有哪些 编辑:程序博客网 时间:2024/06/05 21:57
题目比较简单,用splay动态维护一个可以整体删除的集合,
不需要打下标,打个上标维护size求kth,
用delta记录偏移即可完成所有操作。
调试了两个小时,后来发现因初始工资而走的员工不能算是走的员工,题目中没说明,太坑了。
在splay中,常用INF哨兵,但我没发现有人用null哨兵,我发现null哨兵能够大幅简化代码,同时具有一定的容错性。
程序的容错性非常重要,即使参数正常也最好写个指针检查,不要在乎这点常数,当访问到null甚至是NULL的时候做特殊处理,即使不可能出现这种情况,在很多情况下也能救你一命。
如果我的Splay代码还有可以优化的地方请联系我!!
不需要打下标,打个上标维护size求kth,
用delta记录偏移即可完成所有操作。
调试了两个小时,后来发现因初始工资而走的员工不能算是走的员工,题目中没说明,太坑了。
在splay中,常用INF哨兵,但我没发现有人用null哨兵,我发现null哨兵能够大幅简化代码,同时具有一定的容错性。
程序的容错性非常重要,即使参数正常也最好写个指针检查,不要在乎这点常数,当访问到null甚至是NULL的时候做特殊处理,即使不可能出现这种情况,在很多情况下也能救你一命。
如果我的Splay代码还有可以优化的地方请联系我!!
#include <cstdio>#include <cstdlib>#include <climits>using namespace std;#define INF (INT_MAX/2)struct Node { int val,size,mul; Node *ch[2],*father; Node(int _val,int _mul,Node *_null):val(_val),size(_mul),mul(_mul) { ch[0]=ch[1]=father=_null; } void setch(int w,Node *v) { ch[w]=v; v->father=this; } void rot() { Node *u=father; int w=(u->ch[0]==this); u->setch(!w,ch[w]); u->father->setch(u->father->ch[1]==u,this); setch(w,u); u->size=u->ch[0]->size+u->ch[1]->size+u->mul; }} *null=new Node(0,0,(Node*)0);Node *root=null; void splay(Node *v,Node *goodfather){ for(Node *u;(u=v->father)!=goodfather;v->rot()) if(u->father!=goodfather) (((u->ch[0]==v)==(u->father->ch[0]==u->father))?u:v)->rot();v->size=v->ch[0]->size+v->ch[1]->size+v->mul; if(goodfather==null) root=v;} Node *S_lower(int x){ Node *ans=null; for(Node *u=root;u!=null;u=u->ch[u->val<x]) { if(u->val==x) return u; if(u->val>x) ans=u; } return ans;} Node *S_upper(int x){ Node *ans=null; for(Node *u=root;u!=null;u=u->ch[u->val<x]) { if(u->val==x) return u; if(u->val<x) ans=u; } return ans;} void s_insert(int goodval){ if(root==null) {root=new Node(goodval,1,null);return;} Node *res=null,*u=root; while(true) { int w=u->val<goodval; if(u->val==goodval) { ++(res=u)->mul; break; } else if(u->ch[w]==null) { u->setch(w,res=new Node(goodval,1,null)); break; } else u=u->ch[w]; } splay(res,null);} int s_delete(int l,int r){ splay(S_upper(l),null); splay(S_lower(r),root); Node *seg=root->ch[1]->ch[0]; if(seg==null) return 0; root->ch[1]->ch[0]=null; (root->ch[1])->size=(root->ch[1])->ch[0]->size+(root->ch[1])->ch[1]->size+(root->ch[1])->mul; root->size=root->ch[0]->size+root->ch[1]->size+root->mul; return seg->size;} Node *s_kth(int k){ if(k<1) return null; Node *u=root; while(k<=u->size) { int q1=u->ch[0]->size,q2=q1+u->mul; if(k<=q1) u=u->ch[0]; else if(k>q2) {k-=q2;u=u->ch[1];} else {splay(u,null);return u;} } return null;} int main(){ int case_cnt,minval,num_go=0,delta=0; scanf("%d%d",&case_cnt,&minval); s_insert(-INF);s_insert(INF); while(case_cnt--) { char cmd[6]; int k; scanf("%s%d",cmd,&k); if(cmd[0]=='I') { k-=delta; if(k<minval-delta) ;//++num_go;>o<怎么可以这样?!!! else s_insert(k); } else if(cmd[0]=='A') { delta+=k; } else if(cmd[0]=='S') { delta-=k; num_go+=s_delete(-INF,minval-delta);//!!!!!! } else if(cmd[0]=='F') { Node *v=s_kth(root->size-2-k+1+1); if(v==null || v->val>=INF || v->val<=-INF) printf("-1\n"); else printf("%d\n",v->val+delta); } } printf("%d\n",num_go); return 0;}
0 0
- (题解)(Splay)NOI2004郁闷的出纳员
- 【NOI2004】郁闷的出纳员(splay)
- bzoj1503 [NOI2004]郁闷的出纳员(splay)
- 【NOI2004】郁闷的出纳员(splay tree WA中。。)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- BZOJ 1503 [NOI2004] :郁闷的出纳员(Splay)
- [NOI2004]郁闷的出纳员 (Splay)
- NOI2004郁闷的出纳员题解
- NOI2004郁闷的出纳员题解
- 【NOI2004】郁闷的出纳员 // SPLAY TREE
- bzoj 1503 [NOI2004]郁闷的出纳员 splay
- 【NOI2004】【splay】【SBT】郁闷的出纳员
- BZOJ 1503 [NOI2004]郁闷的出纳员 (splay)
- [BZOJ1503]NOI2004 郁闷的出纳员|splay
- 【bzoj1503】[NOI2004]郁闷的出纳员 Splay
- 1503: [NOI2004]郁闷的出纳员【splay】
- 【BZOJ1503】[NOI2004]郁闷的出纳员【Splay】
- 数字游戏
- 怎么xxx.app一直都是红色的? 编译了很多次 显示成功,但就是红色
- 《C算法》笔记7:词法解析树
- Sdoi2015约数个数和题解莫比乌斯反演
- 小结-sprintf()
- (题解)(Splay)NOI2004郁闷的出纳员
- IOS 获取设备相关特性
- TCP与UDP的区别
- 动态数组封装实现向量类
- exchange2013的搜索邮件跟踪日志功能
- 同一服务器上启动多个数据库的方法及常见问题
- C++ Primer : 第十二章 : 动态内存之unique_ptr和weak_ptr
- CodeForces-447C DZY Loves Sequences
- Pixhawk---烧写FMU/IO bootloader