bzoj 1503[NOI 2004] 郁闷的出纳员
题目大意:
给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] 郁闷的出纳员的更多相关文章
- [bzoj 1503][NOI 2004]郁闷的出纳员(平衡树)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1503 分析: 经典的平衡树题,我用Treap做的 下面有几点注意的: 1.可能出现新加入的人的 ...
- 洛谷 P1486 BZOJ 1503 NOI 2004 郁闷的出纳员 fhq treap
思路: 1. 此处的fhq treap的分裂是按照权值分裂然后插入的.将小于k的分为一棵子树,大于等于k的分为另一棵子树. 2. 删除的时候只要将大于等于min的分裂到以root为根的树中,另一部分不 ...
- 数据结构(跳跃表):NOI 2004 郁闷的出纳员
郁闷的出纳员 [问题描述] OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常, ...
- NOI 2004 郁闷的出纳员(平衡树)
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- NOI 2004 郁闷的出纳员
Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...
- 【BZOJ 1503】[NOI2004]郁闷的出纳员
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 因为所有人工资同时递减. 所以可以设置一个变化值delta. 然后每个人的初始值为k 则把k-delta加入伸展树中. 会发现del ...
- 【NOI】2004 郁闷的出纳员
[算法]平衡树(treap) [题解] treap知识见数据结构. 解法,具体细节见程序. #include<cstdio> #include<algorithm> #incl ...
- 【BZOJ】【1503】 【NOI2004】郁闷的出纳员
Splay Splay的模板题吧……妥妥的序列操作= =(好像有段时间没写过这种纯数据结构题了……) /************************************************ ...
- bzoj 1503郁闷的出纳员(splay)
1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 11759 Solved: 4163[Submit][Stat ...
随机推荐
- solr查询优化【转】filtercache
solr查询优化(实践了一下效果比较明显) 什么是filtercache? solr应用中为了提高查询速度有可以利用几种cache来优化查询速度,分别是fieldValueCache,queryRes ...
- 图解GitHub
转自:http://marklodato.github.io/visual-git-guide/index-zh-cn.html 个人觉得这一篇比一些入门教程更值得看,图解很详细到位,很容易理解其工作 ...
- qt project settings被禁用解决方案
转载请注明出处:http://www.cnblogs.com/dachen408/p/7422707.html qt project settings被禁用点击不了: 解决方案:需要点击该项目(或者项 ...
- win10忘记wifi记录
1.点击桌面右下角无线图标 2.点击网络设置 3.点击管理WIFI设置 4.点击要管理的账户,忘记或者共享该wifi.
- Window.Event.KeyCode的含义
Window.Event.KeyCode=13的含义(转载) 2011-04-16 09:41:18| 分类: html | 标签:keycode event realkey var do ...
- ubuntu 安装 pcap
最近在做负载均衡配置,希望将多个dhcp服务配置成一个虚拟dhcp地址,实现dhcp服务高可用.然而配置完成后却发现一个问题,该如何测试呢. 因此就要用上python了,然后ubuntu下面用pip ...
- process data
# version 1.0def connect_mysql(sql, oper_type="select", data_l=None): conn = pymysql.conne ...
- 漫谈Word2vec之skip-gram模型
https://zhuanlan.zhihu.com/p/30302498 陈运文 复旦大学 计算机应用技术博士 40 人赞同了该文章 [作者] 刘书龙,现任达观数据技术部工程师,兴趣方向主要为自 ...
- JavaScript设计模式基础之面向对象的JavaScript(二)
多态 多态的实际含义:同一操作作用与不同的对象上面,可以产生不同的解释和不同的执行结果,就是说,给不同的对象发送同一个消息 的时候,这些对象会根据这个消息分别给出不同的反馈 代码如下: class D ...
- bzoj 3555 企鹅QQ
https://www.lydsy.com/JudgeOnline/problem.php?id=3555 枚举每一位字符,计算字符两侧的哈希值,然后进行比较,用map或排序记录出与其相同的字符串数量 ...