P5356 [Ynoi Easy Round 2017] 由乃打扑克 Solution

Description

给定序列 a = ( a 1 , a 2 , ⋯ , a n ) a=(a_1,a_2,\cdots,a_n) a=(a1,a2,,an),有 m m m 个操作分两种:

  • add ⁡ ( l , r , x ) \operatorname{add}(l,r,x) add(l,r,x):对每个 i ∈ [ l , r ] i\in[l,r] i[l,r] 执行 a i ← a i + x a_i\gets a_i+x aiai+x.
  • kth ⁡ ( l , r , k ) \operatorname{kth}(l,r,k) kth(l,r,k):求 a l ⋯ r a_{l\cdots r} alr 中第 k k k 小的值,无解输出 − 1 -1 1.

Limitations

1 ≤ n , m ≤ 1 0 5 1\le n,m\le 10^5 1n,m105
∣ a i ∣ , ∣ x ∣ ≤ 2 × 1 0 4 |a_i|,|x| \le 2\times 10^4 ai,x2×104
2 s , 128 MB 2\text{s},128\text{MB} 2s,128MB

Solution

看到这种很难维护的操作,考虑分块,每块分别拷贝一份 p i p_i pi 并进行升序排序.
先考虑 kth ⁡ \operatorname{kth} kth,先取 a l ⋯ r a_{l\cdots r} alr 中的最小值和最大值.
k = 1 k=1 k=1,答案为最小值,若 k = r − l + 1 k=r-l+1 k=rl+1,答案为最大值,若超出范围则为 − 1 -1 1,否则以最小值和最大值为左右端点,进行二分.
对于 check ⁡ \operatorname{check} check,求出区间内不大于 mid \textit{mid} mid 的数的个数,具体就是散块暴力,整块二分,外层二分出的结果就是答案.

再考虑 add ⁡ \operatorname{add} add,整块显然打上 tag \textit{tag} tag
对于散块,由于 a i a_i ai p i p_i pi 都要更新,我们将加过 x x x 和没加过 x x x 的部分分成两个数组,再进行归并.

注意分块的标记是永久化的,计算时不要漏了.
要开 long long,否则会被 hack.

Code

4.48 KB , 11.20 s , 3.92 MB (in total, C++20 with O2) 4.48\text{KB},11.20\text{s},3.92\text{MB}\;\texttt{(in total, C++20 with O2)} 4.48KB,11.20s,3.92MB(in total, C++20 with O2)

#include <bits/stdc++.h>
using namespace std;using i64 = long long;
using ui64 = unsigned long long;
using i128 = __int128;
using ui128 = unsigned __int128;
using f4 = float;
using f8 = double;
using f16 = long double;template<class T>
bool chmax(T &a, const T &b){if(a < b){ a = b; return true; }return false;
}template<class T>
bool chmin(T &a, const T &b){if(a > b){ a = b; return true; }return false;
}#ifdef LOCAL
#define getchar_unlocked getchar
#define putchar_unlocked putchar
#endiftemplate<class T>
inline T read() {T x = 0, f = 1;char ch = getchar_unlocked();while (ch < '0' || ch > '9') {if (ch == '-') f = -1;ch = getchar_unlocked();}while (ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48);ch = getchar_unlocked();}return x * f;
}template<class T>
inline void write(T x) {if (x < 0) {putchar_unlocked('-');x = -x;}if (x > 9) write(x / 10);putchar_unlocked(x % 10 + '0');return;
}constexpr int B = 256;
constexpr i64 inf = 6e18;
struct Node {i64 val;int pos;inline Node() {}inline Node(i64 _val, int _pos) : val(_val), pos(_pos) {}bool operator<(const Node& rhs) const { return val < rhs.val; }
};struct Block {int n, blocks;vector<i64> a, tag;vector<int> belong, L, R;vector<Node> p, t1, t2;inline Block() {}inline Block(const vector<i64>& _a) : a(_a) {n = a.size();blocks = (n + B - 1) / B;p.resize(n), belong.resize(n);L.resize(blocks), R.resize(blocks), tag.resize(blocks);for (int i = 0; i < blocks; i++) {L[i] = i * B;R[i] = min(L[i] + B, n) - 1;for (int j = L[i]; j <= R[i]; j++) {belong[j] = i;p[j] = Node(a[j], j);}sort(p.begin() + L[i], p.begin() + R[i] + 1);}}inline pair<i64, i64> bound(int l, int r) {int bl = belong[l], br = belong[r];i64 vl = inf, vr = -inf;if (bl == br) {for (int i = l; i <= r; i++) {vl = min(vl, a[i] + tag[bl]);vr = max(vr, a[i] + tag[bl]);}}else {for (int i = l; i <= R[bl]; i++) {vl = min(vl, a[i] + tag[bl]);vr = max(vr, a[i] + tag[bl]);}for (int i = L[br]; i <= r; i++) {vl = min(vl, a[i] + tag[br]);vr = max(vr, a[i] + tag[br]);}for (int i = bl + 1; i < br; i++) {vl = min(vl, p[L[i]].val + tag[i]);vr = max(vr, p[R[i]].val + tag[i]);}}return {vl, vr};}inline int count(int l, int r, int k) {int res = 0, bl = belong[l], br = belong[r];if (bl == br) {for (int i = l; i <= r; i++) res += (a[i] + tag[bl] <= k);}else {for (int i = l; i <= R[bl]; i++) res += (a[i] + tag[bl] <= k);for (int i = L[br]; i <= r; i++) res += (a[i] + tag[br] <= k);for (int i = bl + 1; i < br; i++) {int vl = L[i], vr = R[i];if (p[vl].val + tag[i] > k) continue;if (p[vr].val + tag[i] <= k) {res += vr - vl + 1;continue;}while (vl < vr) {int mid = ((vl + vr) >> 1) + 1;if (p[mid].val + tag[i] <= k) vl = mid;else vr = mid - 1;}if (p[vl].val + tag[i] <= k) res += vl - L[i] + 1;}}return res;}inline i64 kth(int l, int r, int k) {auto [vl, vr] = bound(l, r);const int len = r - l + 1;if (k == 1) return vl;if (k == len) return vr;if (k < 1 || k > len) return -1;i64 res = -1;while (vl <= vr) {i64 mid = (vl + vr) >> 1;if (count(l, r, mid) < k) vl = mid + 1;else vr = (res = mid) - 1;}return res;}inline void msort(int l, int r, int b, int k) {t1.clear(), t2.clear();for(int i = L[b]; i <= R[b]; i++) {if (i >= l && i <= r) a[i] += k;if (p[i].pos >= l && p[i].pos <= r) t1.push_back(Node(p[i].val + k, p[i].pos));else t2.push_back(p[i]);}int lp = 0, rp = 0, ptr = L[b];while (ptr <= R[b]) {if (lp < t1.size() && (rp >= t2.size() || t1[lp].val < t2[rp].val)) p[ptr++] = t1[lp++];else p[ptr++] = t2[rp++];}}inline void add(int l, int r, int k) {int bl = belong[l], br = belong[r];msort(l, r, bl, k);if (bl != br) {msort(l, r, br, k);for (int i = bl + 1; i < br; i++) tag[i] += k;}}
};signed main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);const int n = read<int>(), m = read<int>();vector<i64> a(n);for (int i = 0; i < n; i++) a[i] = read<i64>();Block blk(a);for (int i = 0, op, l, r, k; i < m; i++) {op = read<int>(), l = read<int>(), r = read<int>(), k = read<int>();l--, r--;if (op == 1) write(blk.kth(l, r, k)), putchar_unlocked('\n');else blk.add(l, r, k);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39359.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常见中间件漏洞之四:Apache

1. CVE-2021-41773 Apache HTTP Server 路径穿越漏洞 漏洞简介 该漏洞是由于Apache HTTP Server 2.4.49版本存在⽬录穿越漏洞,在路径穿越⽬录<Directory/>Require all granted</Directory>允许被访问的的情况下&#xff08;默认开启&#xff09;&#xff0c;攻击…

Pytorch中Tensorboard的学习

1、Tensorboard介绍 TensorBoard 是 TensorFlow 开发的一个可视化工具&#xff0c;用于帮助用户理解和调试机器学习模型的训练过程。尽管它最初是为 TensorFlow 设计的&#xff0c;但通过 PyTorch 的 torch.utils.tensorboard 模块&#xff0c;PyTorch 用户也可以方便地使用 Te…

刷机维修进阶教程-----adb禁用错了系统app导致无法开机 如何保数据无损恢复机型

在刷机维修过程中 。我们会遇到一些由于客户使用adb指令来禁用手机app而导致手机无法开机进入系统的故障机型。通常此类问题机型有好几种解决方法。但如果客户需要保数据来恢复机型。其实操作也是很简单的.还有类似误删除应用导致不开机等等如何保数据。 通过博文了解💝💝�…

哪吒汽车:一边熬夜蹦迪,一边找药投医

两年前&#xff0c;威马CEO沈晖发了个短视频&#xff0c;内容是“活下去&#xff0c;像牲口一样活下去”。 如今最能体会沈晖当时心情的&#xff0c;估计就是方运舟了。 作为哪吒汽车创始人兼董事长&#xff0c;他连续多次被限高&#xff0c;为了让哪吒汽车活下去&#xff0c…

2025 cs144 Lab Checkpoint 1小白超详细版

cs144官网&#xff1a;https://cs144.github.io/ 我的github&#xff1a;https://github.com/Albert-tru/cs144-2025 文章目录 1 手动发送internet数据报协议号5、7&#xff1f;思路&#xff1f; 2 实现一个Reassembler类2.1 几个帮助理解代码的Q&AQ1&#xff1a;insert的参…

使用 OpenCV 拼接进行图像处理对比:以形态学操作为例

图像处理在计算机视觉中起着至关重要的作用&#xff0c;而 OpenCV 作为一个强大的图像处理库&#xff0c;提供了丰富的函数来实现各类图像处理任务。形态学操作&#xff08;Morphological Operations&#xff09;是其中常用的技术&#xff0c;尤其适用于二值图像的处理。常见的…

单链表的查找和插入,删除操作

1.单链表的查找 snode* slistfind(snode* stlheap, stltype x) {while (stlheap){if (stlheap->data x){return stlheap;}stlheap stlheap->next;}return NULL; } 2.单链表的插入操作 2.1在指定位置之前插入节点 void slistinsert(snode** stlheap, snode* pos, stl…

一文速通Python并行计算:00 并行计算的基本概念

一文速通 Python 并行计算&#xff1a;00 并行计算的基本概念 摘要&#xff1a; 该文介绍了 Python 并行计算的核心概念、编程模型及其应用&#xff0c;并介绍了了并行程序的性能分析与优化方法&#xff0c;如并行效率、加速比及 Amdahl 定律。此外&#xff0c;该文介绍了共享…

vue中keep-alive组件的使用

keep-alive是vue的内置组件&#xff0c;它的主要作用是对组件进行缓存&#xff0c;避免组件在切换时被重复创建和销毁&#xff0c;从而提高应用的性能和用户体验。它自身不会渲染一个 DOM 元素&#xff0c;也不会出现在父组件链中。使用时&#xff0c;只需要将需要缓存的组件包…

Python Excel表格数据对比工具

【Excel对比工具】提升工作效率的神奇助手&#xff1a;基于PyQt5和Pandas的文件数据对比应用 相关资源文件已经打包成EXE文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Python相关程序案例…

注册登录表单

html登录页面&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>创建一个登录页面</t…

JAVA:Spring Boot @Conditional 注解详解及实践

1、简述 在 Spring Boot 中&#xff0c;Conditional 注解用于实现 条件化 Bean 装配&#xff0c;即根据特定的条件来决定是否加载某个 Bean。它是 Spring 框架中的一个扩展机制&#xff0c;常用于实现模块化、可配置的组件加载。 本文将详细介绍 Conditional 相关的注解&…

Java高频面试之集合-17

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;JDK 8 对 HashMap 主要做了哪些优化呢&#xff1f;为什么要这么做&#xff1f; JDK 8 对 HashMap 的主要优化及原因 JDK…

力扣DAY24 | 热100 | 回文链表

前言 简单 √ 是反转链表的衍生题&#xff0c;很快写完了。不过没考虑到恢复链表结构的问题。 题目 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输…

Unity跨平台构建快速回顾

知识点来源&#xff1a;人间自有韬哥在&#xff0c;豆包 目录 一、发布应用程序1. 修改发布必备设置1.1 打开设置面板1.2 修改公司名、游戏项目名、版本号和默认图标1.3 修改 Package Name 和 Minimum API Level 2. 发布应用程序2.1 配置 Build Settings2.2 选择发布选项2.3 构…

手敲NLP相关神经网络,熟悉神经网络的结构与实现!

一、NNLM 二、word2vec 三、TextCNN 四、TextRNN 五、TextLSTM 六、Bi-LSTM 七、seq2seq 八、seq2seq&#xff08;attention&#xff09;

Spring MVC 拦截器使用

javaweb过滤器和springmvc拦截器&#xff1a; 拦截器的概念 拦截器使用 1/创建拦截器类&#xff0c;类中实现 handler执行前&#xff0c;执行后与渲染视图后的具体实现方法 public class GlobalExceptionHandler implements HandlerInterceptor {// if( ! preHandler()){re…

数据库分类、存储引擎、介绍、Mysql、SQL分类

DAY17.1 Java核心基础 数据库 关系型数据库&#xff08;传统数据库&#xff0c;安全可靠&#xff0c;数据量大&#xff09;&#xff1a;Mysql、Oracle、SQLServer 非关系型数据库nosql&#xff08;缓存数据库&#xff0c;高并发项目中&#xff0c;存储热点数据&#xff0c;短信…

Extend module 01:Keyboard

目录 一、Keyboard &#xff08;1&#xff09;资源介绍 &#x1f505;原理图 &#x1f505;扫描原理 &#xff08;2&#xff09;STM32CubeMX 软件配置 &#xff08;3&#xff09;代码编写 &#xff08;4&#xff09;实验现象 二、Keyboard接口函数封装 三、踩坑日记 &a…

【机器人】复现 GrainGrasp 精细指导的灵巧手抓取

GrainGrasp为每个手指提供细粒度的接触指导&#xff0c;为灵巧手生成精细的抓取策略。 通过单独调整每个手指的接触来实现更稳定的抓取&#xff0c;从而提供了更接近人类能力的抓取指导。 论文地址&#xff1a;GrainGrasp: Dexterous Grasp Generation with Fine-grained Con…