Description

给出一个下限 \(m\) ,要求维护以下操作

  1. 插入一个数(如果小于下限就不加)
  2. 给每个数加上一个数
  3. 给每个数减去一个数,并且删除掉 \(< m\) 的所有数
  4. 求目前第 \(k\) 大的数(注意是第 \(k\) 大!从大到小排序后第 \(k\) 个)

    最后还要输出所有 3 操作一共删掉了多少个数

    \(n \leq 10^5\)

Solution

fhqtreap大法吼!

由于修改操作是全体操作,可以用一个 \(delta\) 记录修改总量

对于 1 操作插入权值 \(x - delta\)(如果 x <= m 就算了

对于 2 操作直接把 \(delta += x\)

对于 3 操作,先把 \(delta -= x\) ,然后把小于 \(m - delta\) 的全部删掉

具体实现可以 split 出来两个子树,然后直接让 root = 右子树,最后要输出的 ans += 左子树的 siz

对于 4 操作,split一下就行了

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 100100;
int n, m, delta;
struct node {
int d, rnd, siz;
node *ch[2];
inline void upd() {
int ret = 1; if(ch[0]) ret += ch[0]->siz;
if(ch[1]) ret += ch[1]->siz; siz = ret;
}
}pool[N], *cur = pool, *root;
inline int siz(node *p) { return p ? p->siz : 0; }
inline node *New(int d) { node *p = (cur++); p->d = d, p->siz = 1, p->rnd = rand(); return p; }
inline node *merge(node *p, node *q) {
if(!p || !q) return p ? p : q;
if(p->rnd < q->rnd) { p->ch[1] = merge(p->ch[1], q); p->upd(); return p; }
if(p->rnd >= q->rnd) { q->ch[0] = merge(p, q->ch[0]); q->upd(); return q; }
return 0;
}
inline void split(node *r, int k, node *&p, node *&q) {
if(!r) { p = q = 0; return ; }
if(siz(r->ch[0]) >= k) q = r, split(r->ch[0], k, p, r->ch[0]);
else p = r, split(r->ch[1], k - siz(p->ch[0]) - 1, r->ch[1], q); r->upd();
}
inline int rk(node *r, int x) {
return !r ? 0 : (r->d >= x ? rk(r->ch[0], x) : (siz(r->ch[0]) + 1 + rk(r->ch[1], x)));
}
inline node *del(int x) {
int k = rk(root, x); node *p, *q;
split(root, k, p, q); root = q; return p;
}
int main() { int ans = 0;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) {
char op[5]; int d;
scanf("%s %d", op, &d);
if(op[0] == 'I') {
if(d < m) continue ;
if(!root) { root = New(d - delta); continue ; }
node *p, *q; split(root, rk(root, d - delta), p, q);
root = merge(merge(p, New(d - delta)), q);
} else if(op[0] == 'A') delta += d;
else if(op[0] == 'S') {
delta -= d; node *p = del(m - delta);
ans += siz(p);
} else {
// printf("%d\n", siz(root));
if(siz(root) < d) { printf("-1\n"); continue ; }
int sizz = siz(root);
node *p, *q, *r; split(root, (sizz - d + 1) - 1, p, q);
split(q, 1, q, r); printf("%d\n", q->d + delta); root = merge(merge(p, q), r);
}
} printf("%d\n", ans);
return 0;
}

题解【bzoj1503 [NOI2004]郁闷的出纳员】的更多相关文章

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

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

  2. [BZOJ1503][NOI2004]郁闷的出纳员 无旋Treap

    1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MB Description OIER公司是一家大型专业化软件公司,有着数以万计的员 ...

  3. bzoj1503: [NOI2004]郁闷的出纳员(伸展树)

    1503: [NOI2004]郁闷的出纳员 题目:传送门 题解: 修改操作一共不超过100 直接暴力在伸展树上修改 代码: #include<cstdio> #include<cst ...

  4. bzoj1503 [NOI2004]郁闷的出纳员(名次树+懒惰标记)

    1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 8705  Solved: 3027[Submit][Statu ...

  5. 【题解】 bzoj1503: [NOI2004]郁闷的出纳员 (Splay)

    bzoj1503,懒得复制,戳我戳我 Solution: 我知不知道我是那根筋抽了突然来做splay,调了起码\(3h+\),到第二天才改出来(我好菜啊),当做训练调错吧 一个裸的splay,没啥好说 ...

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

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

  7. BZOJ1503[NOI2004]郁闷的出纳员——treap

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

  8. [luogu1486][bzoj1503][NOI2004]郁闷的出纳员【平衡树treap】

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

  9. BZOJ1503 [NOI2004]郁闷的出纳员 splay

    原文链接http://www.cnblogs.com/zhouzhendong/p/8086240.html 题目传送门 - BZOJ1503 题意概括 如果某一个员工的工资低于了min,那么,他会立 ...

随机推荐

  1. MyForm_参考django的Form组建

    fork wupeiqi:https://github.com/fat39/Tyrion 组件说明:https://www.cnblogs.com/wupeiqi/p/5938916.html

  2. “秒杀”问题的数据库和SQL设计【转载】

    “秒杀”问题的数据库和SQL设计 APRIL 21ST, 2015 问题的来源 完全不考虑一致性的方案 表结构 方案 存在的问题 保证单用户不会重复购买 解决超卖问题 方案 优化 提高性能了 鱼与熊掌 ...

  3. 20162314 《Program Design & Data Structures》Learning Summary Of The Ninth Week

    20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Ninth Week ...

  4. 任务看板-Monday

    工作照

  5. c++第七次作业____最后的总结

    先言: 在这过程中学到: 第二次作业Github的使用 第四次作业计算器的计算 ps:表达式处理以及计算 第五次作业文件的处理问题 第六次作业界面的设计 总结: 1.这学期的计算器,做的有点匆忙,偶尔 ...

  6. Git初用心得

    第一次使用git,因为之前操作系统的实验需要,在虚拟机中使用过lniux系统,所以对这种用指令输入而不是图形化的程序感觉不是很陌生.感觉git还是很人性化的,git gui就是图形界面,操作起来也不复 ...

  7. 微信之父张小龙经典演讲164页PPT:《微信背后的产品观》

    收藏地址:http://www.haokoo.com/internet/8974068.html

  8. 二叉查找树ADT--C语言描述

    首先给出此ADT的声明: struct TreeNode; typedef struct TreeNode *Position; typedef struct TreeNode *SearchTree ...

  9. PAT 甲级 1010 Radix

    https://pintia.cn/problem-sets/994805342720868352/problems/994805507225665536 Given a pair of positi ...

  10. HDU 2078 复习时间

    http://acm.hdu.edu.cn/showproblem.php?pid=2078 Problem Description 为了能过个好年,xhd开始复习了,于是每天晚上背着书往教室跑.xh ...