[NOI 2004]郁闷的出纳员
来源:互联网 发布:手机取色软件 编辑:程序博客网 时间:2024/04/29 11:40
这是一道练手的水题啦!写网络流怕把splay忘了,于是来练习一下splay。这是一道很经典的splay入门题,用size域查询排名,维护的仍然是有序表,只是由于涉及到删除插入的操作,包括询问排名,所以线段树不是很好实现(但事实上是可以的)。
尽管是道很基础的题,但是还是有很多地方值得注意:
1、由于员工工资可能是一样的,所以如果让重复的元素出现在树中,则会使删除操作变得异常麻烦。于是我们应该添加一个num域表示当前元素在树中出现的个数。那么有两个操作将被修改:
(1). 在进行update更新时,函数应变成
this->size=l->size+r->size+this->num;
(2). 查找第k大的元素也应该修改,具体看代码
2、在进行删除操作时,千万不能删多了,这个有一些写法上的技巧。
3、splay的关键地方必须及时更新,否则可能会出现奇怪的错误。
4、这个题目的大坑点,如果某员工开始时工资低于最低工资标准,那么他不用算在离开的人数内(出题人语文没学好O__O"…)。
#include <cstdio>#define __add(x,w) lazy[x]+=w,a[x]+=w#define update(x) if((x)) s[x]=s[l[x]]+s[r[x]]+num[x]#define MaxN 100010using namespace std;int a[MaxN],l[MaxN],r[MaxN],num[MaxN],s[MaxN],lazy[MaxN];int n,low,t,tot,ans;inline void push(const int &x){if(!x) return;__add(l[x],lazy[x]);__add(r[x],lazy[x]);lazy[x]=0;}inline void zig(int &x){int lc=l[x];l[x]=r[lc];r[lc]=x;update(x);x=lc;}inline void zag(int &x){int rc=r[x];r[x]=l[rc];l[rc]=x;update(x);x=rc;}inline void splay(int &t,int x){if(!t) return;int p,pl=0,pr=0,last;for(;;){push(t);push(l[t]);push(r[t]);if(x==a[t]) break;if(x<a[t]&&!l[t]) break;if(x>a[t]&&!r[t]) break;if(x<a[t]){if(x<a[l[t]]&&l[l[t]]) zig(t);p=l[t],l[t]=pr,pr=t,t=p;}else{if(x>a[r[t]]&&r[r[t]]) zag(t);p=r[t],r[t]=pl,pl=t,t=p;}}last=l[t];while(pl){p=r[pl],r[pl]=last;update(pl);last=pl,pl=p;}l[t]=last;last=r[t];while(pr){p=l[pr],l[pr]=last;update(pr);last=pr,pr=p;}r[t]=last;update(t);}inline void insert(const int &x){if(x<low) return;splay(t,x);if(!t) a[++tot]=x,t=tot;if(x==a[t]){num[t]++;update(t);}else{a[++tot]=x;num[tot]++;if(x<a[t])l[tot]=l[t],l[t]=tot;elser[tot]=r[t],r[t]=tot;update(tot);update(t);}}inline void cheak(){splay(t,low);if(a[t]<low) splay(r[t],a[t]),zag(t);ans+=s[l[t]];l[t]=0;update(t);}inline int ask(int &x){if(x>s[t]) return -1;int temp=t,cmp;for(;;){push(temp);push(l[temp]);push(r[temp]);cmp=s[r[temp]]+num[temp];if(x<=cmp&&x>s[r[temp]])return a[temp];else if(x<=s[r[temp]])temp=r[temp];elsex-=cmp,temp=l[temp];}}int main(){//freopen("in","r",stdin);//freopen("out","w",stdout);char s[2];int x;scanf("%d%d",&n,&low);while(n--){scanf("%s%d",s,&x);if(s[0]=='I')insert(x);else if(s[0]=='A')__add(t,x);else if(s[0]=='S')__add(t,-x),cheak();else printf("%d\n",ask(x));}printf("%d",ans);return 0;}
0 0
- 【NOI 2004】 郁闷的出纳员
- [NOI 2004]郁闷的出纳员
- [NOI 2004]郁闷的出纳员
- [noi 2004] 郁闷的出纳员
- NOI 2004 郁闷的出纳员
- [NOI 2004] 郁闷的出纳员
- NOI 2004 郁闷的出纳员 Splay
- 【Treap】[NOI 2004]郁闷的出纳员
- AVL树 郁闷的出纳员 [NOI 2004] [平衡树解法]
- BZOJ 1503 [NOI 2004] 郁闷的出纳员 (splay)
- [Vijos P1507][NOI 2004]郁闷的出纳员(Treap)
- 【BZOJ 1503】【NOI 2004】郁闷的出纳员【treap】
- splay树解决NOI的郁闷的出纳员
- NOI 郁闷的出纳员 (Spay树、平衡树操作)
- noi2004 郁闷的出纳员
- [NOI2004]郁闷的出纳员
- NOI04郁闷的出纳员
- NOI2004 郁闷的出纳员
- [C#/ASP.NET]List<>中Sort()、Find()、FindAll()、Exist()的使用方法
- [网络流24题 #4]魔术球问题
- NoSQL数据库笔谈
- Ubuntu下用arm-none-linux-gnueabi交叉编译libxml2
- session token 防止表单重复提交
- [NOI 2004]郁闷的出纳员
- 对双机调试的探索
- RAC 核心概念 Cache Fusion
- jquery 通过css 弹出悬浮框的办法
- 杭电1398
- Arm linux 系统调用分析
- SVN管理的文件不显示状态图标
- 将win7电脑变身WiFi热点,让手机、笔记本共享上网
- Firebug的简介