题目大意:

现在有n个操作和一个最低限度m

\(I\)命令\(I\ k\)新建一个工资档案,初始工资为k。

\(A\)命令$A\ k $把每位员工的工资加上k

\(S\)命令$S\ k $把每位员工的工资扣除k

\(F\)命令$ F\ k\(查询第k多的工资 (如果当前的员工总数不够k,就输出\)-1$)

其中\(n \le 100000\)

最后还要输出最终离开了多少个员工

需要注意的是 ,如果某员工的初始工资低于工资下界,他将立刻离开公司!!!!

一看这个题,就感觉是个\(splay\)了

不过emmmm 这个整体加和整体减应该怎么弄呢

我们考虑维护一个整体的变化值\(tmp\)

那么对于splay中的每个元素,它的实际权值就是\(x+tmp\)

这么来说

对于\(I\)操作,如果它的权值\(>\)m,则\(insert(x-tmp)\)

对于\(A\)操作,直接\(tmp+=x\)

对于\(S\)操作,我们让\(tmp-=x\),并且判断有没有需要退出的点(就是直接将\(-inf\)转到\(root\),然后把\(min1-tmp-1\)的后继转到root的右儿子,删掉左儿子)这样做的原因是避免哨兵被删掉

对于\(F\)操作,那就直接返回第k大,然后\(+tmp\)就可以

代码还是有很多细节的,比如要维护当前平衡树中有几个元素,事先加入哨兵之类的,直接看代码吧

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<vector> using namespace std; inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
} const int maxn = 1e6+1e2; int ch[maxn][4];
int val[maxn],sz[maxn],size;
int fa[maxn];
int cnt[maxn];
int n,m,ymh,root,min1;
int tot;
int num=0;
int ans; int son(int x)
{
if (x==ch[fa[x]][0]) return 0;
else return 1;
}
void update(int x)
{
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x];
} void rotate(int x)
{
int y=fa[x],z=fa[y];
int b=son(x),c=son(y);
ch[z][c]=x;
fa[x]=z;
ch[y][b]=ch[x][!b];
fa[ch[x][!b]]=y;
ch[x][!b]=y;
fa[y]=x;
update(y);
update(x);
} void splay(int x,int p)
{
while (fa[x]!=p)
{
int y=fa[x],z=fa[y];
if (z==p) rotate(x);
else
{
if (son(x)==son(y))
{
rotate(y);
rotate(x);
}
else
{
rotate(x);
rotate(x);
}
}
}
if (fa[x]==0) root=x;
} int find_qq(int x)
{
int now = root,num=0;
while (now)
{
if (val[now]<x)
{
num=now;
now=ch[now][1];
}
else now=ch[now][0];
}
return num;
} int find_hj(int x)
{
int now = root,num=0;
while (now)
{
if (val[now]>x)
{
num=now;
now=ch[now][0];
}
else now=ch[now][1];
}
return num;
} void insert(int x)
{
tot++;
int qq = find_qq(x);
int hj = find_hj(x);
splay(qq,0);
splay(hj,qq);
int y = ch[hj][0];
if (cnt[y])
{
cnt[y]++;
update(y);
}
else
{
++size;
ch[hj][0]=size;
fa[size]=hj;
val[size]=x;
cnt[size]=1;
sz[size]=1;
//cout<<"gg11"<<endl;
update(size);
}
} void delet(int x)
{
--tot;
int qq = find_qq(x);
int hj = find_hj(x);
splay(qq,0);
splay(hj,qq);
int y = ch[hj][0];
if (cnt[y]>1)
{
cnt[y]--;
update(y);
}
else
{
cnt[y]=0;
fa[y]=0;
ch[hj][0]=0;
sz[y]=0;
val[y]=0;
}
} int kth(int x)
{
int now = root;
while (1)
{
if (x<=sz[ch[now][0]]) now=ch[now][0];
else{
if (x<=sz[ch[now][0]]+cnt[now]) return val[now];
x-=sz[ch[now][0]]+cnt[now];
now=ch[now][1];
}
}
} int add; int main()
{
size=2;
val[1]=2e9;
val[2]=-2e9;
fa[2]=1;
ch[1][0]=2;
root=1;
scanf("%d%d",&n,&min1);
for (int i=1;i<=n;i++)
{
char s[10];
int x;
scanf("%s",s+1);
//cout<<size<<endl;
x=read();
//cout<<x<<endl;
if (s[1]=='A')
{
ymh+=x;
}
if (s[1]=='S')
{
ymh-=x;
int hj = find_hj(min1-ymh-1);
splay(2,0);
splay(hj,2);
int pos = ch[hj][0];
ans+=sz[pos];
tot-=sz[pos];
fa[pos]=0;
ch[hj][0]=0;
sz[pos]=0;
cnt[pos]=0;
/*if (tot==0)
{
size=2;
val[1]=2e9;
val[2]=-2e9;
fa[2]=1;
ch[1][0]=2;
root=1;
}*/
//cout<<ans;
}
if (s[1]=='I')
{
if (x<min1) continue;
//cout<<"gg"<<endl;
insert(x-ymh);
}
if (s[1]=='F')
{
//cout<<tot<<endl;
if (x>tot)
printf("-1\n");
else
printf("%d\n",kth(tot-x+1)+ymh);
}
//cout<<tot<<endl;
}
cout<<ans;
return 0;
}

bzoj1503 郁闷的出纳员(平衡树,思维)的更多相关文章

  1. Luogu P1486 [NOI2004]郁闷的出纳员(平衡树)

    P1486 [NOI2004]郁闷的出纳员 题意 题目描述 \(OIER\)公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作 ...

  2. bzoj1503 郁闷的出纳员

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

  3. [BZOJ1503]郁闷的出纳员(Splay)

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

  4. BZOJ1503——郁闷的出纳员

    1.题目大意:一道treap题,支持插入,询问第K大,还有全体修改+上一个值,如果某个点值小于x,那么就删除这个点 插入100000次,询问100000次,修改100次..最后输出删了多少个点 2.分 ...

  5. bzoj1503 郁闷的出纳员 splay版

    自己yy的写法 可能有点奇怪吧 详情看代码 还是蛮短的 #include<cstdio> #include<cstring> #include<algorithm> ...

  6. [BZOJ1503][NOI2004]郁闷的出纳员

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

  7. 洛谷P1486 [NOI2004]郁闷的出纳员 [STL,平衡树]

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

  8. 平衡树 - Luogu 1486 郁闷的出纳员

    这么久没写平衡树了,再来一发... P1486 郁闷的出纳员 题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的 ...

  9. 【bzoj1503】[NOI2004]郁闷的出纳员

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

随机推荐

  1. win10 uwp 通过 Win2d 完全控制笔迹绘制逻辑

    本文来告诉大家如何通过 Win2d 完全控制笔迹绘制逻辑,本文适合用来实现复杂的自定义逻辑,可以完全控制笔迹的行为.包括在书写过程中切换模式,如进行手势擦除切换为橡皮擦模式 本文提供的方法适合用来做复 ...

  2. 100个裁判对n个选手做无并列排名问题探析

    原题:n 个选手(n ≥ 3)参加花样自行车比赛,100 个裁判独立对各选手的表现给出无并列排名.已知对任意三个选手 A.B.C 和任意三个裁判 X.Y.Z 均不会出现如下的情形:X 给出 A > ...

  3. 微服务架构及raft协议

    微服务架构全景图 服务注册和发现 Client side implement 调用需要维护所有调用服务的地址 有一定的技术难度,需要rpc框架支持 Server side implement 架构简单 ...

  4. Docker编排工具Docker Compose的使用

    一.安装docker compose 官网推荐方式之一: sudo curl -L "https://github.com/docker/compose/releases/download/ ...

  5. 洛谷P2424 约数和 题解

    题目 约数和 题解 此题可以说完全就是一道数学题,不难看出这道题所求的是 \(\sum\limits_{i=x}^{y}{\sum\limits_{d|i}{d}}\) 的值. 很显然,用暴力枚举肯定 ...

  6. docker-compose up -d nginx 报错

    在阿里云ECS上创建nginx容器时,报错如上图. The solution: In your Dockerfile, before running any apt commands, add the ...

  7. SpringBoot-异步定时-邮件任务

    目录 背景 异步任务 定时任务 邮件任务 背景 在我们的工作中,常常会用到异步处理任务,比如我们在网站上发送邮件, 后台会去发送邮件,此时前台会造成响应不动,直到邮件发送完毕,响应才会成功, 所以我们 ...

  8. RMI源码调试

    看RMI漏洞时候,对其漏洞原理并不是很理解,所以简单调试了下源码加强下漏洞理解 由于要调试到RegistryImpl_Stub这种动态类,刚开始用的源码版本是JDK8u141,后来发现源码有些地方进行 ...

  9. [第十一篇]——Docker 仓库管理之Spring Cloud直播商城 b2b2c电子商务技术总结

    Docker 仓库管理 仓库(Repository)是集中存放镜像的地方.以下介绍一下 Docker Hub.当然不止 docker hub,只是远程的服务商不一样,操作都是一样的. Docker H ...

  10. 导出excel、word、csv文件方法汇总

    http://www.woaic.com/2012/06/64 excel文件主要是输出html代码.以xls的文本格式保存文件. 生成excel格式的代码: /// <summary> ...