题目大意:

给4种操作

I:添加一个员工工资信息

A:增加所有员工的工资

S:减少所有员工的工资

F:询问工资第k高的员工的工资情况

自己做的第一道splay树的题目,初学找找感觉

 #include <cstdio>
#include <cstring>
#include <iostream> using namespace std;
int n,m,w,limit;
const int N = ;
#define ls ch[x][0]
#define rs ch[x][1]
struct SplayTree{
//sum[i]记录i以及其子树中的点的总个数,cnt[i]记录与i号位置取值相等的点的个数
int val[N] , cnt[N] , sum[N];
int all; //统计离开公司的员工的总人数,也就是相当于计算删除的点的个数
int ch[N][];
int pre[N];
int rt , top; void init()
{
ch[][] = ch[][] = pre[] = sum[] = cnt[] = ;
all = rt = top = ;
} void newNode(int &x , int c)
{
x = ++top;
ch[x][] = ch[x][] = pre[x] = ;
cnt[x] = sum[x] = , val[x]=c;
}
//通过左右子节点更新父节点
void up(int x){
sum[x] = sum[ch[x][]]+sum[ch[x][]]+cnt[x];
} void Rotate(int x , int f) //f==1表示右旋,也就是x属于父亲的左子树上
{
int y=pre[x];
ch[y][!f] = ch[x][f];
pre[ch[x][f]]=y;
if(pre[y]) ch[pre[y]][ch[pre[y]][]==y]=x;
pre[x]=pre[y];
pre[y]=x;
ch[x][f]=y;
up(y);
} void Splay(int x , int goal)
{
while(pre[x] != goal){
if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][] == x);
else{
int y=pre[x] , z=pre[y];
int f=(ch[z][] == y);
if(ch[y][f] == x) Rotate(x , !f) , Rotate(x , f);
else Rotate(y,f) , Rotate(x,f);
}
}
up(x);
if(goal == ) rt = x;
} void insert(int &x , int key , int fa)
{
//一直向下找到空的叶子节点插入当前的值
if(!x){
newNode(x , key);
pre[x]=fa;
Splay(x , );
return;
}
if(key == val[x]){
cnt[x]++;
sum[x]++;
Splay(x,);
return ;
}
//点插入左子树
else if(key<val[x]){
insert(ch[x][] , key , x);
}
//点插入右子树
else {
insert(ch[x][] , key , x);
}
up(x);
} void del(int &x , int fa)
{
//一直访问到空的叶子节点结束
if(!x) return ;
//当前点的工资满足要求,那么只要考虑其左子树上要删除多少点
if(val[x] >= limit) del(ch[x][] , x);
else{
/*当前点的工资不满足要求,那么这个点和其左子树都是不满足要求的
,all记录当前点和左子树删除的点的总数*/
all+=sum[ch[x][]]+cnt[x];
x=ch[x][];
//当前点被删除,连接关系要进行修改
pre[x]=fa;
if(fa == ) rt = x;
del(x,fa);
}
if(x) up(x);
} void update()
{
del(rt , );
} int find_kth(int x , int k)
{
if(k<sum[ch[x][]]+) return find_kth(ch[x][] , k);
else if(k > sum[ch[x][]]+cnt[x])
return find_kth(ch[x][] , k-sum[ch[x][]]-cnt[x]);
else{
Splay(x , );
return x;
}
}
}spt; int main()
{
// freopen("a.in" , "r" , stdin);
char op[];
int t;
while(~scanf("%d%d" , &n , &m))
{
spt.init();
for(int i= ; i<n ; i++){
scanf("%s%d" , op , &t);
if(op[] == 'I'){
if(t<m)
continue;
spt.insert(spt.rt , t-w , );
}
else if(op[] == 'A') w+=t;
else if(op[] == 'S'){
w-=t;
limit=m-w;
spt.update();
}
else{
int sum = spt.sum[spt.rt];
if(t>sum) printf("-1\n");
else{
printf("%d\n" , spt.val[spt.find_kth(spt.rt , sum-t+)]+w);
}
}
// cout<<"sum: "<<spt.sum[spt.rt]<<endl;
}
printf("%d\n" , spt.all);
}
return ;
}

bzoj 1503[NOI 2004] 郁闷的出纳员的更多相关文章

  1. [bzoj 1503][NOI 2004]郁闷的出纳员(平衡树)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1503 分析: 经典的平衡树题,我用Treap做的 下面有几点注意的: 1.可能出现新加入的人的 ...

  2. 洛谷 P1486 BZOJ 1503 NOI 2004 郁闷的出纳员 fhq treap

    思路: 1. 此处的fhq treap的分裂是按照权值分裂然后插入的.将小于k的分为一棵子树,大于等于k的分为另一棵子树. 2. 删除的时候只要将大于等于min的分裂到以root为根的树中,另一部分不 ...

  3. 数据结构(跳跃表):NOI 2004 郁闷的出纳员

    郁闷的出纳员 [问题描述] OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常, ...

  4. NOI 2004 郁闷的出纳员(平衡树)

    题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...

  5. NOI 2004 郁闷的出纳员

    Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...

  6. 【BZOJ 1503】[NOI2004]郁闷的出纳员

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 因为所有人工资同时递减. 所以可以设置一个变化值delta. 然后每个人的初始值为k 则把k-delta加入伸展树中. 会发现del ...

  7. 【NOI】2004 郁闷的出纳员

    [算法]平衡树(treap) [题解] treap知识见数据结构. 解法,具体细节见程序. #include<cstdio> #include<algorithm> #incl ...

  8. 【BZOJ】【1503】 【NOI2004】郁闷的出纳员

    Splay Splay的模板题吧……妥妥的序列操作= =(好像有段时间没写过这种纯数据结构题了……) /************************************************ ...

  9. bzoj 1503郁闷的出纳员(splay)

    1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 11759  Solved: 4163[Submit][Stat ...

随机推荐

  1. solr查询优化【转】filtercache

    solr查询优化(实践了一下效果比较明显) 什么是filtercache? solr应用中为了提高查询速度有可以利用几种cache来优化查询速度,分别是fieldValueCache,queryRes ...

  2. 图解GitHub

    转自:http://marklodato.github.io/visual-git-guide/index-zh-cn.html 个人觉得这一篇比一些入门教程更值得看,图解很详细到位,很容易理解其工作 ...

  3. qt project settings被禁用解决方案

    转载请注明出处:http://www.cnblogs.com/dachen408/p/7422707.html qt project settings被禁用点击不了: 解决方案:需要点击该项目(或者项 ...

  4. win10忘记wifi记录

    1.点击桌面右下角无线图标 2.点击网络设置 3.点击管理WIFI设置 4.点击要管理的账户,忘记或者共享该wifi.

  5. Window.Event.KeyCode的含义

    Window.Event.KeyCode=13的含义(转载) 2011-04-16 09:41:18|  分类: html |  标签:keycode  event  realkey  var  do ...

  6. ubuntu 安装 pcap

    最近在做负载均衡配置,希望将多个dhcp服务配置成一个虚拟dhcp地址,实现dhcp服务高可用.然而配置完成后却发现一个问题,该如何测试呢. 因此就要用上python了,然后ubuntu下面用pip ...

  7. process data

    # version 1.0def connect_mysql(sql, oper_type="select", data_l=None): conn = pymysql.conne ...

  8. 漫谈Word2vec之skip-gram模型

    https://zhuanlan.zhihu.com/p/30302498 陈运文 ​ 复旦大学 计算机应用技术博士 40 人赞同了该文章 [作者] 刘书龙,现任达观数据技术部工程师,兴趣方向主要为自 ...

  9. JavaScript设计模式基础之面向对象的JavaScript(二)

    多态 多态的实际含义:同一操作作用与不同的对象上面,可以产生不同的解释和不同的执行结果,就是说,给不同的对象发送同一个消息 的时候,这些对象会根据这个消息分别给出不同的反馈 代码如下: class D ...

  10. bzoj 3555 企鹅QQ

    https://www.lydsy.com/JudgeOnline/problem.php?id=3555 枚举每一位字符,计算字符两侧的哈希值,然后进行比较,用map或排序记录出与其相同的字符串数量 ...