1 条题解
-
0
题意
有 个应聘者,每人有一个整数“评价值”。
我们要处理 次操作,操作分两类:- 查询():给定 ,聘用所有评价值 的人。被聘用的人按连续编号分组,即:如果 和 都被聘用,并且 之间的所有人也被聘用,则 和 在同一组。问此时有多少组。
- 修改():给定 ,将第 个应聘者的评价值改为 。
样例 1 解释
初始评价值:
- 第一次查询 :聘用 (评价值 )。
分组: 连续聘用, 单独一组,共 组。 - 修改:第 个应聘者评价值改为 。
- 查询 :聘用 ,一组,输出 。
- 查询 :聘用 ,分组: 一组, 一组,共 组。
思路分析
关键观察
设我们聘用的员工集合是:所有 的人。
把他们按编号从小到大排序,分组规则是:连续的一段被聘用的员工属于同一组。
所以,组数 = 聘用的员工数 - 相邻聘用员工中编号连续的对数。更具体地:
$$\text{groups} = k - \#\{i \mid p_{i+1} = p_i + 1\} $$
设聘用的员工编号为 (已排序),那么组数即:组数 = 聘用人数 - 相邻聘用且编号连续的对数。
如何快速计算
对于给定的 ,我们要数出:
- 有多少个 满足 (聘用人总数)。
- 有多少对相邻的 满足 且 (这些会减少组数,因为 和 在同一组)。
那么:
$$\text{答案} = \text{count\_ge}(B) - \text{count\_adj\_ge}(B) $$其中 是 的人数, 是满足 且 的相邻对 的数量。
数据结构选择
我们需要支持:
- 单点更新 。
- 查询:给定 ,快速得到 和 。
这可以用两个 Fenwick 树(树状数组) 或 线段树 实现,按值域维护。
具体做法:
- 对值域离散化(因为 范围大,但总数 )。
- 第一个 Fenwick 树
cnt维护每个值有多少个 等于它(用于求 )。 - 第二个 Fenwick 树
adj维护每个值有多少对相邻的 的最小值 该值(用于求 )。
更新操作
当修改 从 变为 时:
- 更新
cnt:在 处 -1,在 处 +1。 - 更新相邻关系:影响 和 这两对。
- 先删除旧值对这两对的贡献(在
adj中,在 处 -1,在 处 -1)。 - 更新 为 。
- 再添加新值对这两对的贡献(在 处 +1,在 处 +1)。
- 先删除旧值对这两对的贡献(在
查询操作
给定 :
- 。
- 。
用 Fenwick 树可以 求后缀和。
复杂度
- 离散化
- 每次操作
- 总
- 1
信息
- ID
- 4092
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者