950. 郁闷的出纳员

题目链接

950. 郁闷的出纳员

OIER 公司是一家大型专业化软件公司,有着数以万计的员工。

作为一名出纳员,我的任务之一便是统计每位员工的工资。

这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。

如果他心情好,就可能把每位员工的工资加上一个相同的量。

反之,如果心情不好,就可能把他们的工资扣除一个相同的量。

我真不知道除了调工资他还做什么其它事情。

工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。

每位员工的工资下界都是统一规定的。

每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。

老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第 k 多的员工拿多少工资。

每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。

好了,现在你已经对我的工作了解不少了。

正如你猜的那样,我想请你编一个工资统计程序。

怎么样,不是很困难吧?

输入格式

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

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

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

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

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

输出格式

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

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

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

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

数据范围

I 命令的条数不超过 105
A 命令和 S 命令的总条数不超过 100
F 命令的条数不超过 105
每次工资调整的调整量不超过 1000
新员工的工资不超过 105

输入样例:

9 10 I 60 I 70 S 50 F 2 I 30 S 15 A 5 F 1 F 2

输出样例:

10 20 -1 2

解题思路

splay

由于每次插入一个数,都按照值在中序遍历中的位置插入,而所有的操作都不改变 splay 所维护的中序遍历的顺序,所以整个操作中 splay 维护的中序遍历的值是有序的,而本题关键在于删除一个区间,删除一个区间往往引入两个哨兵 inf,inf,其中 L 表示值为 inf 的节点,不妨用 d 记下目前增减操作的值,而每次删除节点时,要求删除的节点表示的值 x,满足 inf<x+d<mn,则需删除 splay 中表示值为 [0,mnd) 的节点,则需将这些节点放在一棵子树上便于删除,则需找到最小满足 xmndx 的代表的节点 R,然后有两种方法将所求区间变为一棵子树:1. splay(R,0),splay(L,R),此时 L 的右子树即为所求;2. splay(L,0),splay(R,L),此时 R 的左子树即为所求

  • 时间复杂度:O(nlogn)

代码

// Problem: 郁闷的出纳员 // Contest: AcWing // URL: https://www.acwing.com/problem/content/952/ // Memory Limit: 64 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=1e5+5,inf=1e8; int root,cnt,d,n,mn,k,res; struct Tr { int s[2],sz,p,v; void init(int _p,int _v) { p=_p,v=_v; } }tr[N]; void pushup(int u) { tr[u].sz=tr[tr[u].s[0]].sz+tr[tr[u].s[1]].sz+1; } void rotate(int x) { int y=tr[x].p,z=tr[y].p; int k=tr[y].s[1]==x; tr[z].s[tr[z].s[1]==y]=x,tr[x].p=z; tr[y].s[k]=tr[x].s[k^1],tr[tr[x].s[k^1]].p=y; tr[x].s[k^1]=y,tr[y].p=x; pushup(y),pushup(x); } void splay(int x,int k) { while(tr[x].p!=k) { int y=tr[x].p,z=tr[y].p; if(z!=k) { if((tr[z].s[1]==y)^(tr[y].s[1]==x))rotate(x); else rotate(y); } rotate(x); } if(!k)root=x; } int insert(int v) { int u=root,p=0; while(u)p=u,u=tr[u].s[v>tr[u].v]; u=++cnt; if(p)tr[p].s[v>tr[p].v]=u; tr[u].init(p,v); splay(u,0); return u; } int find(int val) { int u=root,res=-1; while(u) { if(tr[u].v>=val)res=u,u=tr[u].s[0]; else u=tr[u].s[1]; } return res; } int get_k(int k) { int u=root; while(u) { if(tr[tr[u].s[0]].sz>=k)u=tr[u].s[0]; else if(tr[tr[u].s[0]].sz+1==k)return tr[u].v; else k-=tr[tr[u].s[0]].sz+1,u=tr[u].s[1]; } return -1; } int main() { scanf("%d%d",&n,&mn); int L=insert(-inf),R=insert(inf); while(n--) { char op[2]; scanf("%s%d",op,&k); if(*op=='I') { if(k>=mn)insert(k-d),res++; } else if(*op=='A')d+=k; else if(*op=='S') { d-=k; int R=find(mn-d); // splay(R,0),splay(L,R); // tr[L].s[1]=0; // pushup(R),pushup(L); splay(R,0),splay(L,R); tr[L].s[1]=0; pushup(L),pushup(R); } else { if(tr[root].sz-2<k)puts("-1"); else printf("%d\n",get_k(tr[root].sz-k)+d); } } printf("%d",res+2-tr[root].sz); return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16460015.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示