题目链接

题目

题目描述

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

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. 每天学五分钟 Liunx 1000 | 软件篇:源码安装

    软件安装流程 前面软件篇提到了通过 RPM 和 YUM 在线安装的机制安装软件,除了这两种方式之外还有一种通过源码来安装软件的方式.

  2. 打 multi-fidelity RL 旗号,但是幼稚监督学习 + 迁移学习

    文章名称:Multi-fidelity reinforcement learning framework for shape optimization 链接:https://www.sciencedi ...

  3. linux 通过docker安装 elasticsearch-head

    本文为博主原创,未经允许不得转载: 1. 使用docker安装 elasticsearch-head #拉取镜像 docker pull mobz/elasticsearch-head:5 #创建容器 ...

  4. Spring cloud gateWay 限流器限流(一)

    转载请注明出处: spring cloud 提供了限流操作的功能,其使用步骤如下: 1.引入maven依赖: <dependency> <groupId>org.springf ...

  5. js - 使用 scroll属性手撸轮播图 —— 无缝连接,更丝滑

    上效果图: 上代码: <!DOCTYPE html> <html lang="en"> <head>     <meta charset= ...

  6. PG数据库存储验证

    PG数据库存储验证 背景 最近学习了SQLServer数据库的varchar和nvarchar的存储 想到PG数据库其实没让选择字符集,也没有nvarchar 所以想学习一下nvarchar的使用情况 ...

  7. [转帖]调试springboot数据库系统应用时常用debug日志配置, 解决问题缩小范围时常用

    https://www.yihaomen.com/article/1853.html 摘要: 用 spring boot 开发应用时,在遇到麻烦问题时,经常会打开debug日志,下面记录一个通用的思路 ...

  8. [转帖]xsos - Summarize system info from sosreports

    https://github.com/ryran/rsar I'M LOOKING FOR RSAR SCREEN SHOTS INTRO INSTALLATION EXAMPLES IN ACTIO ...

  9. js中的宏任务和微任务详细讲解

    微任务有哪些 Promise await和async 宏任务有哪些 setTimeout setInterval DOM事件 AJAX请求 看下面的代码 <script> console. ...

  10. 【小测试】golang中数组边界检查的开销大约是1.87%~3.12%

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 对比C/C++, golang等类型安全的语言会在数组访问 ...