NC208250 牛牛的最美味和最不美味的零食
题目
题目描述
牛牛为了减(吃)肥(好),希望对他的零食序列有更深刻的了解,所以他把他的零食排成一列,然后对每一个零食的美味程度都打了分,现在他有可能执行两种操作:
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\) 个点,有两种情况:
- 若左子区间的有效点数大于等于 \(k\) ,那么要修改的点就在左子区间。
- 否则在右子区间。
要查询当前区间 \([l,r]\) 的值也是同理,有三种情况:
- 若左子区间的有效点大于等于 \(r\) ,则查询左子区间。
- 否则若左子区间的有效点小于 \(l\) ,则查询右子区间。
- 否则可以确定查询区间跨越了左右子区间,则两边都要查询。
这道题展示了线段树上二分查找点、区间的基本写法,是个值得一做的好题。
时间复杂度 \(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 牛牛的最美味和最不美味的零食的更多相关文章
- bzoj4571: [Scoi2016]美味
4571: [Scoi2016]美味 Time Limit: 30 Sec Memory Limit: 256 MB Submit: 275 Solved: 141 [Submit][Status][ ...
- 【BZOJ4571】美味(主席树)
[BZOJ4571]美味(主席树) 题面 Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 ...
- 【bzoj4571 scoi2016】美味
题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi .因此,第 ...
- 【bzoj4571&&SCOI2016美味】
4571: [Scoi2016]美味 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 656 Solved: 350[Submit][Status][ ...
- bzoj 4571: [Scoi2016]美味 (主席树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4571 题面; 4571: [Scoi2016]美味 Time Limit: 30 Sec ...
- luogu P3293 [SCOI2016]美味
题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi .因此,第 ...
- BZOJ4517[Scoi2016]美味——主席树
题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 i 位顾客认为 ...
- BZOJ4571:[SCOI2016]美味(主席树,贪心)
Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi . 因此,第 ...
- P3293 [SCOI2016]美味
题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi .因此,第 ...
- BZOJ4571: [Scoi2016]美味【主席树】【贪心】
Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 ...
随机推荐
- Kubernetes APIServer 最佳实践
1. kubernetes 整体架构 kubernetes 由 master 节点和工作节点组成.其中,master 节点的组件有 APIServer,scheduler 和 controller-m ...
- AMBA总线介绍-01
AMBA总线介绍 AMBA总线概述 AHB APB 不同IP之间的互连 1.系统总线简介 系统芯片中各个模块之间需要有接口连接,使用总线作为子系统之间共享的通信链路 优点:成本低,方便易用(通用协议, ...
- Linux-搜索-文件-find-locate-内容过滤-grep
- [转帖]MySQL数据类型(decimal的存储大小)
本来还以为MySQL的数据类型挺简单的,没想到竟然有很多坑,容我仔细道来 MySQL数据类型 整数类型(注意是字节) 浮点型(重点关注decimal) 字符型(注意这是4.x版本的定义,5.x以后已经 ...
- [转帖]jmeter无图形界面执行测试并生成报告
1.进入jmeter的安装目录,找到bin文件夹,进入这个文件执行以下命名 jmeter -n -t test\xxx.jmx -l test\cli0705.jtl -e -o test\resul ...
- Kafka学习之四_Grafana监控相关的学习
Kafka学习之四_Grafana监控相关的学习 背景 想一并学习一下kafaka的监控. 又重新开始学习grafana了: 下载地址: https://grafana.com/grafana/dow ...
- Python学习之二:不同数据库相同表是否相同的比较方法
摘要 昨天学习了使用python进行数据库主键异常的查看. 当时想我们有跨数据库的数据同步场景. 对应的我可以对不同数据库的相同表的核心字段进行对比. 这样的话能够极大的提高工作效率. 我之前写过很长 ...
- [转帖]linux性能优化-内存回收
linux文件页.脏页.匿名页 缓存和缓冲区,就属于可回收内存.它们在内存管理中,通常被叫做文件页(File-backed Page). 通过内存映射获取的文件映射页,也是一种常见的文件页.它也可以被 ...
- Linux 环境下 node 以及 jit 的简单环境配置说明
注意事项: 1. 注意这个包需要实时更新. 2. 更新时需要按照目录覆盖文件. 3. 谁负责谁治理的态度, 有更新,需要完整的进行覆盖安装. 建议先删除旧文件, 替换新文件. 4. 为了简单起见, 直 ...
- [Python] 基于RapidFuzz库实现字符串模糊匹配
RapidFuzz是一个用于快速字符串模糊匹配的Python库,它能够快速计算两个字符串之间的相似度,并提供与Fuzzywuzzy(已停用)和TheFuzz(Fuzzywuzzy的升级版)类似的接口. ...