题目链接

题目

题目描述

牛牛为了减(吃)肥(好),希望对他的零食序列有更深刻的了解,所以他把他的零食排成一列,然后对每一个零食的美味程度都打了分,现在他有可能执行两种操作:

eat k:吃掉当前的第k个零食。右边的零食全部往左移动一位(编号减一)。

query i j:查询当前第i个零食到第j个零食里面美味度最高的和最低的零食的美味度。

输入描述

第一行包含两个数n, m,表示原始数组的元素个数和操作的个数。第二行包括n个数,表示原始数组。以下m行,每行格式为1 k或者2 i j,其中第一个数为1表示吃掉,为2表示询问。

输出描述

对每个询问操作输出一行,包括两个数,表示该范围内的最小值和最大值。

示例1

输入

10 4
1 5 2 6 7 4 9 3 1 5
2 2 8
1 3
1 6
2 2 8

输出

2 9
1 7

说明

\(1 \leq n, m \leq 10^6\) , \(1 \leq m \leq 10^6\) ,数组中的元素绝对值均不超过 \(10^9\)

题解

知识点:线段树,二分。

线段树本身不支持删除操作,我们考虑用区间有效点数代替删除的效果。

比较好的方法是用相对坐标表示查找的点,这样就可以利用线段树上二分来锁定我们要找的点或区间。

要删除当前第 \(k\) 个点,有两种情况:

  1. 若左子区间的有效点数大于等于 \(k\) ,那么要修改的点就在左子区间。
  2. 否则在右子区间。

要查询当前区间 \([l,r]\) 的值也是同理,有三种情况:

  1. 若左子区间的有效点大于等于 \(r\) ,则查询左子区间。
  2. 否则若左子区间的有效点小于 \(l\) ,则查询右子区间。
  3. 否则可以确定查询区间跨越了左右子区间,则两边都要查询。

这道题展示了线段树上二分查找点、区间的基本写法,是个值得一做的好题。

时间复杂度 \(O((n+m) \log n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; struct T {
int sum;
int mi;
int mx;
static T e() { return { 0,(int)2e9,(int)-2e9 }; }
friend T operator+(const T &a, const T &b) {
return {
a.sum + b.sum,
min(a.mi, b.mi),
max(a.mx,b.mx)
};
}
};
class SegmentTree {
int n;
vector<T> node; void update(int rt, int l, int r, int x) {
if (l == r) return node[rt] = { 0,(int)2e9,(int)-2e9 }, void();
int mid = l + r >> 1;
if (node[rt << 1].sum >= x)update(rt << 1, l, mid, x);
else update(rt << 1 | 1, mid + 1, r, x - node[rt << 1].sum);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
} T query(int rt, int l, int r, int x, int y) {
if (x == 1 && node[rt].sum == y) return node[rt];
int mid = l + r >> 1;
if (node[rt << 1].sum >= y) return query(rt << 1, l, mid, x, y);
else if (node[rt << 1].sum < x) return query(rt << 1 | 1, mid + 1, r, x - node[rt << 1].sum, y - node[rt << 1].sum);
else return query(rt << 1, l, mid, x, node[rt << 1].sum) + query(rt << 1 | 1, mid + 1, r, 1, y - node[rt << 1].sum);
} public:
SegmentTree(int _n = 0) { init(_n); }
SegmentTree(int _n, const vector<T> &src) { init(_n, src); } void init(int _n) {
n = _n;
node.assign(n << 2, T::e());
}
void init(int _n, const vector<T> &src) {
init(_n);
function<void(int, int, int)> build = [&](int rt, int l, int r) {
if (l == r) return node[rt] = src[l], void();
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
};
build(1, 1, n);
} void update(int x) { update(1, 1, n, x); } T query(int x, int y) { return query(1, 1, n, x, y); }
}; int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
vector<T> a(n + 1);
for (int i = 1;i <= n;i++) {
int x;
cin >> x;
a[i] = { 1,x,x };
}
SegmentTree sgt(n, a);
while (m--) {
int op;
cin >> op;
if (op == 1) {
int k;
cin >> k;
sgt.update(k);
}
else {
int i, j;
cin >> i >> j;
auto [sum, mi, mx] = sgt.query(i, j);
cout << mi << ' ' << mx << '\n';
}
}
return 0;
}

NC208250 牛牛的最美味和最不美味的零食的更多相关文章

  1. bzoj4571: [Scoi2016]美味

    4571: [Scoi2016]美味 Time Limit: 30 Sec Memory Limit: 256 MB Submit: 275 Solved: 141 [Submit][Status][ ...

  2. 【BZOJ4571】美味(主席树)

    [BZOJ4571]美味(主席树) 题面 Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 ...

  3. 【bzoj4571 scoi2016】美味

    题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi .因此,第 ...

  4. 【bzoj4571&&SCOI2016美味】

    4571: [Scoi2016]美味 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 656  Solved: 350[Submit][Status][ ...

  5. bzoj 4571: [Scoi2016]美味 (主席树)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4571 题面; 4571: [Scoi2016]美味 Time Limit: 30 Sec   ...

  6. luogu P3293 [SCOI2016]美味

    题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi .因此,第 ...

  7. BZOJ4517[Scoi2016]美味——主席树

    题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 i 位顾客认为 ...

  8. BZOJ4571:[SCOI2016]美味(主席树,贪心)

    Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi . 因此,第 ...

  9. P3293 [SCOI2016]美味

    题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi .因此,第 ...

  10. BZOJ4571: [Scoi2016]美味【主席树】【贪心】

    Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 ...

随机推荐

  1. [java] - JavaBeans 获取 session

    RegServlet // 保存到 session request.getSession().setAttribute("user", user); userinfo.jsp // ...

  2. Go-数据类型-布尔类型-bool

    布尔类型--bool 只有两个值 true false 不能转换成其他类型,也不能参加数值运算 布尔应用场景 if swicht for 三大分支语句中的条件部分 比较运算和逻辑运算的返回值 作为通道 ...

  3. 【scikit-learn基础】--『回归模型评估』之偏差分析

    模型评估在统计学和机器学习中具有至关重要,它帮助我们主要目标是量化模型预测新数据的能力. 本篇主要介绍模型评估时,如何利用scikit-learn帮助我们快速进行各种偏差的分析. 1. **R² ** ...

  4. [转帖]Java程序在K8S容器部署CPU和Memory资源限制相关设置

    2019-04-297279 版权 本文涉及的产品 容器服务 Serverless 版 ACK Serverless,317元额度 多规格 推荐场景: 立即试用 容器镜像服务 ACR,镜像仓库100个 ...

  5. [转帖]JMeter InfluxDB v2.0 listener plugin

    https://github.com/mderevyankoaqa/jmeter-influxdb2-listener-plugin Support my Ukrainian Family ️ Lik ...

  6. [转帖]KingbaseES和Oracle数据类型的映射表

    随着数据库国产化的进程,Oracle向KingbaseES数据库的数据迁移需求也越来越多.数据库之间数据迁移的时候,首先遇到的,并且也是最重要的,就是数据类型之间的转换. 下表为KingbaseES和 ...

  7. [换帖]Linux命令之iconv命令

    一.命令简介   日常工作中我们需要将windows生成的文件上传到Linux系统,有时候会因为编码问题出现显示乱码.例如我上传了一个csv文件到Linux服务器上,默认编码为GB2312,在Linu ...

  8. ESXi 虚拟机性能情况简单验证

    1.虚拟化的CPU超售问题. 经过查找资料, 发现 ESXi 5.5 的版本 一个 物理CPU的Core 可以虚拟出 25个vCPU, 升级到ESXi6.0 之后可以虚拟化32个vCPU. 所以虚拟化 ...

  9. 用webpack给js添加上版本号

    在网上查找了很多的资料. 都没有好的资源 因为我现在在项目是vuecli3.0 需要自己去创建文件 在项目的根目录下,创建一个文件vue.config.js 然后在该文件下写 const webpac ...

  10. Paddlenlp之UIE模型实战实体抽取任务【打车数据、快递单】

    项目连接:可以直接fork使用 Paddlenlp之UIE模型实战实体抽取任务[打车数据.快递单] 0.背景介绍 本项目将演示如何通过小样本样本进行模型微调,快速且准确抽取快递单中的目的地.出发地.时 ...