题目大意:

现在有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. Redis(一):安装

    Ubuntu中使用yum安装redis: sudo apt-get install redis-server # 安装redis,安装完成后会自动启动 ps aux|grep redis # 查看进程 ...

  2. new一个对象的时候,实际做了些什么

    当我们说new一个对象的时候,实际做了些什么, 可以参考下图理解

  3. 笔记本+ubuntu18.04 关闭触摸板touchpad

    方法1: Settings -> Devices -> Mouse&Touchpad -> Touchpad OFF 方法2: 终端运行如下命令 touchpad off:  ...

  4. git clone 设置临时的 proxy

    export ALL_PROXY=socks5://127.0.0.1:1086 git clone --depth 1 https://github.com/xxx/xxx.git unset AL ...

  5. 爱思助手备份 iPhone 时没有设置密码,恢复备份时需要密码的问题

    i4.cn 备份时 iPhone 上登陆的 Apple ID 曾经设置过备份密码,这个密码就是恢复备份时需要输入的密码!

  6. HashMap 为什么线程不安全?

    作者:developer http://cnblogs.com/developer_chan/p/10450908.html 我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,但是其线 ...

  7. java基础之反射类型Type

    Java在加入泛型之后,仅仅Class已经不足以描述数据的类型了,比如List<String>类型的数据,其Class的类型为List.class,但是其类型包含了泛型参数,所以java引 ...

  8. samba网络共享

    1.sanma简介 2. samba安装 #更新源 opkg update #搜索软件包,查看版本 opkg list | grep "samba" #根据查询的版本安装服务器和l ...

  9. Python常见问题 - python3 requests库提示警告InsecureRequestWarning的问题

    当使用 requests 库发送请求时报了以下警告 D:\python3.6\lib\site-packages\urllib3\connectionpool.py:847: InsecureRequ ...

  10. 羽夏看Win系统内核——简述

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...