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 ...
随机推荐
- Java基础学习-一切皆为对象
一切皆为对象 引用 String s; //s是引用,并不是对象. String s = "asdf" //创建一个引用的同时便进行初始化
- 使用NPOI操作Excel文件及其日期处理
工作中经常遇到需要读取或导出Excel文件的情况,而NPOI是目前最宜用.效率最高的操作的Office(不只是Excel哟)文件的组件,使用方便,不详细说明了. Excel工作表约定:整个Excel表 ...
- Android 友盟和微信的包冲突:Multiple dex files define Lcom/tencent/a/a/a/a/a;
最近App中有个需求是添加微信支付,就在微信技术官网 http://open.weixin.qq.com,查看一下文档,然后下载SDk,Demo.把SDK集成进项目. 照着微信的文档,把jar包和进来 ...
- checking for gcc... no
./configure 后显示checking for gcc... nochecking for cc... nochecking for cl.exe... noconfigure.sh:erro ...
- JS实现让其他浏览器自动转至微信浏览器打开链接
//判断是否是pc function is_pc() { var sUserAgent = navigator.userAgent.toLowerCase(); var bIsIpad = sUser ...
- 10道有关ios的题
1.你使用过Objective-C的运行时编程(Runtime Programming)么?如果使用过,你用它做了什么?你还能记得你所使用的相关的头文件或者某些方法的名称吗? 2.你实现过多线程的Co ...
- Android(java)学习笔记175:Android进程间通讯(IPC)之AIDL
一.IPC inter process communication 进程间通讯 二.AIDL android interface defination language 安卓接口定义语言 满 ...
- class 写在 import的位置 类的名字第一个字母大写 后面没括号 ES6
class 写在 import的位置 类的名字第一个字母大写 后面没括号 class ObTableDataClass {}或者 const ObTableDataClass = class { in ...
- chrome 打开上次关闭的tab ctrl+shift+T
chrome 打开上次关闭的tab ctrl+shift+T
- 使用Maven构建JavaEE项目
学习要点 Maven简介 Maven构建项目 MyEclipse中Maven的使用 Maven简介 Maven作用 对第三方依赖库进行统一的版本管理 统一的目录结构,统一各平台各IDE目录 统一的软件 ...