这么久没写平衡树了,再来一发...


P1486 郁闷的出纳员

题目描述

OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。

工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。

老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。

好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?

如果某个员工的初始工资低于最低工资标准,那么将不计入最后的答案内

输入

第一行有两个非负整数n和min。n表示下面有多少条命令,min表示工资下界。

接下来的n行,每行表示一条命令。命令可以是以下四种之一:

名称 格式 作用
I命令 I_k 新建一个工资档案,初始工资为k。如果某员工的初始工资低于工资下界,他将立刻离开公司。
A命令 A_k 把每位员工的工资加上k
S命令 S_k 把每位员工的工资扣除k
F命令 F_k 查询第k多的工资

_(下划线)表示一个空格,I命令、A命令、S命令中的k是一个非负整数,F命令中的k是一个正整数。

在初始时,可以认为公司里一个员工也没有。

输出

输出文件的行数为F命令的条数加一。

对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。

输出文件的最后一行包含一个整数,为离开公司的员工的总数。

样例

.in
9 10
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2
.out
10
20
-1
2

说明

I命令的条数不超过100000

A命令和S命令的总条数不超过100

F命令的条数不超过100000

每次工资调整的调整量不超过1000

新员工的工资不超过100000


郁闷的是我们吧

平衡树大裸体题

不过难搞的就是那个工资的增减量

我们存一个变量$ adj \(
每次插进一个结点时把工资减去这个\) adj \(
然后每次批量改工资的时候修改这个\) adj \(
在批量**减去**工资的时候还要split一下
把标准值加上\) adj $再分

split的时候将达到工资下限的保留,不能达到的的扔进另一个树里面

离开的人就是那个树的大小

其余操作都很好搞定

代码蒯上

#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gotcha()
{
register int _a=0;bool _b=1;register char _c=getchar();
while(_c<'0' || _c>'9'){if(_c=='-')_b=0;_c=getchar();}
while(_c>='0' && _c<='9')_a=_a*10+_c-48,_c=getchar();
return _b?_a:-_a;
}
const int _ = 100002;
int seed=19260817;
inline int ou(){return seed=(1ll*seed*17283)%2147483647ll;}
int ch[_][2],d[_],rn[_],sz[_],all=0,n,root=0,trash;
inline void up(int a){sz[a]=sz[ch[a][0]]+sz[ch[a][1]]+1;}
inline int malloc(int a){sz[++all]=1,d[all]=a,rn[all]=ou();return all;}
inline int merge(int a,int b)
{
if(!a || !b)return a+b;
if(rn[a]<rn[b]){ch[a][1]=merge(ch[a][1],b),up(a);return a;}
ch[b][0]=merge(a,ch[b][0]),up(b);return b;
}
void split(int now,int k,int &a,int &b)
{
if(!now){a=b=0;return;}
if(d[now]>k)a=now,split(ch[now][1],k,ch[now][1],b);
else b=now,split(ch[now][0],k,a,ch[now][0]);up(now);
}
void insert(int wgs)
{
int x,y;split(root,wgs,x,y);
root=merge(merge(x,malloc(wgs)),y);
}
int level(int now,int a)
{
while(1)
{
if(a==0 || a==sz[ch[now][0]]+1)return now;
if(a<=sz[ch[now][0]])now=ch[now][0];
else a-=sz[ch[now][0]]+1,now=ch[now][1];
}
}
int lim;
int main()
{
register int t=gotcha(),a,gone=0,adj=0;
register char op[3];
lim=gotcha();
while(t--)
{
scanf("%s",op);a=gotcha();
if(op[0]=='I' && a>=lim)insert(a-adj);
else if(op[0]=='F')
if(a>sz[root])puts("-1");else printf("%d\n",d[level(root,a)]+adj);
else if(op[0]=='A')adj+=a;
else if(op[0]=='S')
adj-=a,split(root,lim-adj-1,root,trash),gone+=sz[trash];
}
printf("%d",gone);
return 0;
}

无旋treap大法吼!

最新文章

  1. AngularJS的Filter用法详解
  2. TYVJ1939 玉蟾宫
  3. 国内常用NTP服务器地址及IP
  4. ffmpeg-2.3.3 configure for android
  5. POJ-1981 Circle and Points 单位圆覆盖
  6. BWT(Burrows-Wheeler Transformation)的讲解及java实现
  7. python 之文本搜索与替换文件中的文本
  8. HTML之组件margin、padding
  9. Ubuntu 12.04和Windows 7双系统安装图解
  10. [luogu P3786]萃香抱西瓜 [spfa][状态压缩]
  11. HDU - 2612 bfs [kuangbin带你飞]专题一
  12. 用SPSS 画 人口金字塔(限SPSS 13.0以上)
  13. 第一阶段——CentOS6_Python3.6.1笔记(尚学堂-Python基础快速入门)+ 【补充】麦子-Python程序入门与进阶
  14. 卷积神经网络总结CNN【转载】
  15. 把button中文字的省略号放到后面
  16. J - MANAGER(2.4.5)
  17. Mysql 数据库几种引擎的区别比较
  18. C# sqlserver ExecuteNonQuery()方法详解
  19. Minimum Window Substring LT76
  20. HAProxy压测及参数调优

热门文章

  1. agc016B - Colorful Hats(智商题)
  2. centos7.3.1611安装及初始配置
  3. 真正理解 git fetch, git pull 以及 FETCH_HEAD(转)
  4. java Vamei快速教程19 嵌套类
  5. 在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务
  6. bzoj3887: [Usaco2015 Jan]Grass Cownoisseur
  7. 2018.6.29 JavaScript
  8. JSON对象转成formData对象,formData对象转成JSON对象
  9. detection in video and image
  10. 关于小程序 scroll-view中设置scroll-top无效 和小说图书阅读进度条小案例