950. 郁闷的出纳员(Splay树)「建议收藏」

950. 郁闷的出纳员(Splay树)「建议收藏」OIER 公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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。

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

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

数据范围
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
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int INF = 1e9;
struct { 
   
    int s[2],p,v;
    int size,add;
    void init(int _v,int _p){ 
   
        v = _v,p = _p;
        size = 1;
    }
}tr[N];
int root,ctx;
int Min;
void pushdown(int u){ 
   
    return;
}
void pushup(int u){ 
   
    tr[u].size = tr[tr[u].s[0]].size + tr[tr[u].s[1]].size + 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 p){ 
   
    while(tr[x].p != p){ 
   
        int y = tr[x].p,z = tr[y].p;
        if(z != p){ 
   
            if((tr[z].s[1] == y) ^ (tr[y].s[1] == x))rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
    if(!p)root = x;
}
int insert(int x){ 
   
    int u = root,p = 0;
    while(u)p = u,u = tr[u].s[x > tr[u].v];
    u = ++ ctx;
    if(p)tr[p].s[x > tr[p].v] = u;
    tr[u].init(x,p);
    splay(u,0);//这里insert不用pushup,因为splay函数会把所有父节点都pushup一遍
    return u;
}
int Find(int v){ 
   //从当前树种找到大于等于v的第一个数
    int u = root,p = 0;
    while(u){ 
   
        if(tr[u].v >= v)p = u,u = tr[u].s[0];
        else u = tr[u].s[1];
    }
    return p;
}
int get_th(int k){ 
   
    int u = root;
    while(u){ 
   
        if(tr[tr[u].s[1]].size >= k)u = tr[u].s[1];
        else if(tr[tr[u].s[1]].size + 1 == k)return tr[u].v;
        else k -= tr[tr[u].s[1]].size + 1,u = tr[u].s[0];
    }
    return -INF;
}
int main(){ 
   
    int n,m,x;
    cin>>n>>m;
    char t;
    int L = insert(-INF),R = insert(INF);
    int delta = 0;
    int res = 0;
    int tot = 0;
    for(int i = 0;i < n;i ++){ 
   
        scanf(" %c %d",&t,&x);
        if(t == 'A')delta += x;
        else if(t == 'S'){ 
   
            delta -= x;
            R = Find(m - delta);
            splay(R,0),splay(L,R);
            res += tr[tr[L].s[1]].size;
            tr[L].s[1] = 0;
            pushup(L),pushup(R);
        }
        else if(t == 'F'){ 
   
            int ans = get_th(x + 1);
            if(ans == -INF)printf("-1\n");
            else printf("%d\n",ans + delta);
        }
        else if(t == 'I'){ 
   
            if(x >= m){ 
   
                x -= delta;
                insert(x);
                tot ++;
            }
        }
    }
    cout<<res<<endl;
    return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/168598.html原文链接:https://javaforall.net

(0)
上一篇 2022年8月9日 下午2:00
下一篇 2022年8月9日 下午2:16


相关推荐

  • (2025年最新)如何在国内升级订阅ChatGPT Plus保姆级教程

    (2025年最新)如何在国内升级订阅ChatGPT Plus保姆级教程

    2026年3月15日
    2
  • Genspark 推出超级智能体:能自主规划、代打电话和思考

    Genspark 推出超级智能体:能自主规划、代打电话和思考

    2026年3月15日
    2
  • 名片设计大全:15款创意设计的名片模板

    名片设计大全:15款创意设计的名片模板每一个公司都需要有一款创造性的 引人注目的名片 设计师们也一直在寻找新的设计概念 今天我们选择了 15 款高质量的专业的名片设计模板 这些精美的名片作品展示了设计师的创意和思想智慧 您可能感兴趣的相关文章名片制作 25 款现代名片设计实例及模板创意无限 25 款很酷的高档名片设计欣赏 50 款免费 PSD 名片设计模板源文件下载创意名片 一组精美的折叠效果名片设计 30 佳别具

    2025年8月30日
    6
  • gitee使用教程,创建项目仓库并上传代码

    gitee使用教程,创建项目仓库并上传代码文章目录一 关于 gitee 二 安装 git 三 登录 gitee 四 生成 SSH 公钥五 配置 SSH 公钥六 创建一个项目七 克隆仓库到本地八 关联本地工程到远程仓库九 添加文件十 执行 git 命令 提交文件十一 常用的 git 命令一 关于 giteegitee 中文名 码云 原名 Git OSC 是开源中国推出的基于 git 的代码托管服务 国内访问 GitHub 速度比较慢 如果想托管自己的代码到云端 gitee 是个不错的选择 华为的鸿蒙 2 0 源码也是放在 gitee 上的 二 安装 git 要使用 gitee 需要先安装 gi

    2026年3月19日
    2
  • Latex中插入多张图片,实现并排排列或者多行多列排列

    Latex中插入多张图片,实现并排排列或者多行多列排列最近需要用latex插入多张图片,达到这么一个效果。但是我原来只插入过一张图片(图片内容来源于网络;是国漫一人之下的宝儿姐。强推这部国漫~),代码如下,效果如图:\begin{figure}\centering\includegraphics[height=4.5cm,width=9.5cm]{111.eps}\caption{pic1}\label{2}\end{figu…

    2022年5月1日
    269
  • 怎么安装wget_Debian安装wget

    怎么安装wget_Debian安装wget第一步:执行wgetwww.baidu.com,若没有,会提示:-bash:wget:commandnotfound第二步:通过这个http://ftp.gnu.org/gnu/wget/下载wget的源代码wget-1.5.3.tar.gz第三步:通过命令行进入到下载后的文件夹,如:cdDownloads第四步:执行tar-zxvfwget-1.5.3.tar….

    2022年10月16日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号