「Good Subarrays」Solution

简述题意

我们定义一个数组 b b b 是好的当且仅当所有的 b i ≥ i b_i \ge i bii
现在给你 q q q 次操作,每次操作有两个数 p p p x x x,求出把 a p a_p ap 赋值成 x x x a a a 数组好的子序列的个数,每次操作独立

  • 1 ≤ n , q ≤ 2 × 1 0 5 1 \le n,q \le 2 \times 10^5 1n,q2×105 1 ≤ a i , p j , x j ≤ n 1 \le a_i,p_j,x_j \le n 1ai,pj,xjn

思路

首先考虑 Easy Version \text{Easy Version} Easy Version 怎么做。

由于没有修改,求子序列的个数问题,一般都是从长度和端点入手。对于此题,考虑求出以 i i i 为开头的满足条件的子序列个数。

注意到,某个元素在子序列和原序列中的下标位置并不一样,所以很难处理。考虑令 c i = a i − i c_i = a_i-i ci=aii(算是一个 Trick \text{Trick} Trick 吧),那么,对于在原序列中的 [ l , r ] [l,r] [l,r],其满足条件就等价于:

∀ i ∈ [ l , r ] , c i + ( l − 1 ) ≥ 0 \forall i \in [l,r],c_i + (l - 1) \ge 0 i[l,r],ci+(l1)0

i ∈ [ l , r ] , m i n { c i } + ( l − 1 ) ≥ 0 i \in [l,r],\mathrm{min\{c_i\}}+(l-1) \ge 0 i[l,r]min{ci}+(l1)0

由于最小值满足单调性,所以当左端点固定时,右端点一定单调,二分求解即可,下令 a n s ans ans 表示未修改时 a a a 中满足条件的子序列个数。

再考虑修改,对于每个 i i i,我们都可以求出一个 r i , R i r_i,R_i ri,Ri r i r_i ri 表示对于 ∀ r ∈ [ i , r i ] \forall r \in [i , r_i] r[i,ri] 都有 [ i , r ] [i,r] [i,r] 是一个合法子序列, R i R_i Ri 表示强制钦定 r i r_i ri 满足条件,即 a r i = i n f a_{r_i} = inf ari=inf 后最靠右的满足 [ i , R i ] [i,R_i] [i,Ri] 是一个合法子序列的点。

由于修改独立,且注意到修改一个点,只会对左边的点产生影响。

所以,对于每次修改 p , x p,x p,x,分成以下三种情况考虑:

  • a p = x a_p=x ap=x,直接输出 a n s ans ans 即可。
  • a p < x a_p<x ap<x,那么显然原来一些不满足条件的子序列现在可能满足条件了。对于某个 i i i,如果原来 r i = p − 1 r_i=p-1 ri=p1,那么就证明 i i i 原来扩展右端点时在 p p p 这个点 “卡住了”,由于这样的 i i i 是连续的( r i ≥ r i − 1 r_i \ge r_{i-1} riri1),不妨二分求出 [ l , r ] [l,r] [l,r] 表示对于 ∀ i ∈ [ l , r ] \forall i \in [l,r] i[l,r] 都满足 r i = p − 1 r_i=p-1 ri=p1。显然,只满足这个条件是不够的,还需满足 m i n { a i , a i + 1 , a i + 2 , . . . , a p − 1 , x − p } + ( i − 1 ) ≥ 0 \mathrm{min\{a_i,a_{i+1},a_{i+2},...,a_{p-1},x-p\}} + (i - 1) \ge 0 min{ai,ai+1,ai+2,...,ap1,xp}+(i1)0 才行,然而这样的 i i i 又是连续的( i i i 越往左越难满足),所以不妨求出同时满足两个条件的 i i i 区间 [ l 2 , r 2 ] [l_2,r_2] [l2,r2],那么对于 i ∈ [ l 2 , r 2 ] i \in [l_2,r_2] i[l2,r2],其对答案的贡献不再是 r i − i + 1 r_i-i+1 rii+1,而是 R i − i + 1 R_i-i+1 Rii+1 了,这个通过前缀和预处理在原答案的基础上更新即可。
  • a p > x a_p>x ap>x,同理可以二分求出 [ l , r ] ( r < i ) [l,r](r < i) [l,r](r<i), 满足 i ∈ [ l , r ] , r i ≥ p i \in[l,r],r_i\ge p i[l,r],rip,然后在 [ l , r ] [l,r] [l,r] 的基础上,二分求出 [ l 2 , r 2 ] [l_2,r_2] [l2,r2], 满足 i ∈ [ l 2 , r 2 ] , m i n { a i , a i + 1 , a i + 2 , . . . . , a p − 1 , x − p } + ( i − 1 ) < 0 i \in [l_2,r_2],\mathrm{min\{a_i,a_{i+1},a_{i+2},....,a_{p-1},x-p\}}+(i-1) < 0 i[l2,r2]min{ai,ai+1,ai+2,....,ap1,xp}+(i1)<0,那么对于 [ l 2 , r 2 ] [l_2,r_2] [l2,r2] 里面的点对答案的贡献不再是 r i − i + 1 r_i-i+1 rii+1,而是 ( p − 1 ) − i + 1 (p-1)-i+1 (p1)i+1,同理前缀和求出即可。

代码

码量并不大,但要注意一下二分的边界和一些 [ l , r ] [l,r] [l,r] [ l 2 , r 2 ] [l_2,r_2] [l2,r2] 不存在的特殊情况。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 2e5 + 5;
int n , q , a[MAXN] , R[MAXN] , RR[MAXN] , Min[MAXN][20];
int idl[MAXN] , idr[MAXN] , pre1[MAXN] , pre2[MAXN];
int GetMin(int l , int r) {int s = log2(r - l + 1);return min(Min[l][s] , Min[r - (1 << s) + 1][s]);
}
int w(int l , int r) {return (l + r) * (r - l + 1) / 2;}
signed main() {ios::sync_with_stdio(false);cin.tie(nullptr) , cout.tie(nullptr);cin >> n;for (int i = 1 ; i <= n ; i ++) cin >> a[i] , Min[i][0] = (a[i] -= i);for (int j = 1 ; j <= 18 ; j ++) {for (int i = 1 ; i + (1 << j) - 1 <= n ; i ++) {Min[i][j] = min(Min[i][j - 1] , Min[i + (1 << j - 1)][j - 1]);}}int lst = 0;for (int i = 1 ; i <= n ; i ++) {int l = i , r = n;while(l < r) {int mid = l + r + 1 >> 1;if (GetMin(i , mid) + (i - 1) >= 0) l = mid;else r = mid - 1;}if (!idl[l]) idl[l] = i;idr[l] = i;R[i] = l , pre1[i] = pre1[i - 1] + (l - i + 1);l = l + 1 , r = n;if (l >= n) {RR[i] = n , pre2[i] = pre2[i - 1] + (n - i + 1);continue;}int ql = l + 1;while(l < r) {int mid = l + r + 1 >> 1;if (GetMin(ql , mid) + (i - 1) >= 0) l = mid;else r = mid - 1;}pre2[i] = pre2[i - 1] + (l - i + 1) , RR[i] = l;}cin >> q;while(q --) {int p , x;cin >> p >> x;x -= p;if (p == 1 || a[p] == x) {cout << pre1[n] << '\n';continue;}if (a[p] < x) {int l = idl[p - 1] , r = idr[p - 1];while(l < r) {int mid = l + r >> 1;if (min(GetMin(mid , p - 1) , x) + (mid - 1) >= 0) r = mid;else l = mid + 1;}if (min(GetMin(l , p - 1) , x) + (l - 1) < 0) cout << pre1[n] << '\n';else cout << pre1[n] + (pre2[idr[p - 1]] - pre2[l - 1]) - (pre1[idr[p - 1]] - pre1[l - 1]) << '\n';} else {int l = 1 , r = p - 1;while(l < r) {int mid = l + r >> 1;if (R[mid] >= p) r = mid;else l = mid + 1;}if (R[l] < p) cout << pre1[n] << '\n';else {int l2 = l , r2 = p - 1;while(l2 < r2) {int mid = l2 + r2 + 1 >> 1;if (min(GetMin(mid , p - 1) , x) + (mid - 1) < 0) l2 = mid;else r2 = mid - 1;}if (min(GetMin(l2 , p - 1) , x) + (l2 - 1) >= 0) cout << pre1[n] << '\n';else cout << pre1[n] - (pre1[l2] - pre1[l - 1]) + w(p - l2 , p - l) << '\n';}}}return 0;
}

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

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

相关文章

[97编程世界冠军4K组]代码被转为ts脚本github代码如何在WIN10运行和调试

源代码地址&#xff1a;iGitHub - SuperSodaSea/Omniscent: Analysis and Replication of Omniscent, the 1st in the Mekka & Symposium 1997 PC 4K Intro Competition. 1、软件安装nodejs和webstorm都要安装&#xff1a; node-v20.12.2-x64.msi WebStorm-2024.1.1.exe 代…

L1-041 寻找250

作者 陈越 单位 浙江大学 对方不想和你说话&#xff0c;并向你扔了一串数…… 而你必须从这一串数字中找到“250”这个高大上的感人数字。 输入格式&#xff1a; 输入在一行中给出不知道多少个绝对值不超过1000的整数&#xff0c;其中保证至少存在一个“250”。 输出格式&a…

【进程通信】利用管道创建进程池(结合代码)

文章目录 什么叫进程池进程池的优点 创建进程池代码实现&#xff1a; 什么叫进程池 我们知道&#xff0c;一个进程创建子进程通常是为了让这个子进程去为它完成某个任务。例如我们使用的指令&#xff0c;其实就是bash进程创建子进程让子进程去执行的。但是我们需要考虑这样一个…

【介绍下分布式系统】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

macos如何安装Tesseract软件

问题在线过程: 今天在mac系统上安装tesseract持续失败,整了很久终于把这个问题解决了,所以希望通过这篇文章分享给大家: 首先,我在用 brew install tesseract 或 brew install --build-from-source tesseract 一直报错,报错内容如下: Warning: You are using macO…

wegame启动游戏错误代码126,加载x3daudio1_7.dll失败的修复教程

在尝试通过WeGame平台启动某款游戏时&#xff0c;遇到了阻碍&#xff0c;系统反馈了一个特定的错误代码“错误代码126&#xff0c;加载x3daudio1_7.dll失败”。这个错误提示表示游戏无法加载x3daudio17.dll文件&#xff0c;导致游戏无法正常启动。经过一番研究和尝试&#xff0…

vue elementui el-table表格 点击单元格添加选中样式

注意&#xff1a; 1、点击某行单元格添加选中样式&#xff1b; 2、表格第一列数据单独添加样式&#xff0c;比如&#xff1a;加粗&#xff1b; 3、表格表头添加样式&#xff0c;比如&#xff1a;修改背景色&#xff1b; 先上代码&#xff08;效果图在文章末尾&#xff09;&…

python-pytorch 如何使用python库Netron查看模型结构(以pytorch官网模型为例)0.9.2

Netron查看模型结构 参照模型安装Netron写netron代码运行查看结果需要关注的地方 2024年4月27日14:32:30----0.9.2 参照模型 以pytorch官网的tutorial为观察对象&#xff0c;链接是https://pytorch.org/tutorials/intermediate/char_rnn_classification_tutorial.html 模型代…

Ansible自动化

Ansible自动化 自动化的需求&#xff1a; 1. 在什么样的场景下需要自动化&#xff1f; 批量化的工作&#xff1a; 装软件包、配置服务、升级、下发文件… 2. 为什么在自动化工具中选择ansible&#xff1f; 对比shell脚本&#xff1a; 相对于用shell的脚本来实现自动化&#x…

42.接雨水

接雨水是一个非常经典的题目了,我在二刷的时候,终于能独立做了,在记录一下灵神的横着计算的单调栈思想. 法一: 竖着计算 奇思妙想 让我们想想,接到的雨水到底是存储哪里了呢,其实他就是凹陷部分,而什么是凹陷呢,就是从左边看,从右边看都发现不了的地方. …

滑块验证码破解----Java使用opencv后端破解滑块验证

使用技术:Java SpringBootopenCV 在windows上首先需要下载opencv进行安装,先去官网:Releases - OpenCV 下载这个windows版本的安装包 下载后直接安装解压就行,然后需要,然后找到安装位置里的这个文件: 你下载的是什么版本的,这里的数字就是多少,比如我下载4.5.3版本那么这…

kubectl无法使用清理磁盘

执行Kubectl get pods 报错如下&#xff1a; # kubectl get nodes The connection to the server <master>:6443 was refused - did you specify the right host or port?查看占用磁盘&#xff1a; df -h 查看占用100%的数据 df -h | grep 100% 检查环境变量&#xff…

(学习日记)2024.04.26:UCOSIII第五十节:User文件夹函数概览(uC-CPU文件夹)

之前的章节都是针对某个或某些知识点进行的专项讲解,重点在功能和代码解释。 回到最初开始学μC/OS-III系统时,当时就定下了一个目标,不仅要读懂,还要读透,改造成更适合中国宝宝体质的使用方式。在学完野火的教程后,经过几经思考,最后决定自己锦上添花,再续上几章。 这…

【数据库】关于数据库你必须知道的事情

常用命令 mysql -u username -p USE mydatabase; SHOW DATABASES; CREATE DATABASE newdatabase;数据库的规约 包括&#xff1a; 建表规约&#xff1b;索引规约&#xff1b;SQL与ORM映射规约&#xff1b; Explain技巧 explain的结果代表的含义需要比较清楚。参数中&#x…

永磁同步电机SMO负载转矩观测matlab模型。

永磁同步电机SMO负载转矩观测matlab模型。 负载转矩的有效识别是提高伺服驱动系统抗负载扰动性能的关键之一。现在的传统结构的LTID滑模观测器存在频率抖动大&#xff0c;估计精度差的缺点&#xff0c;限制了其在高性能伺服系统中的应用。 本模型推导分析了传统LTID滑模观测器…

【k8s】:Pod的生命周期详解

【k8s】:Pod的生命周期详解 1、Pod的生命周期1.1、Pod的创建1.2、Pod的调度1.3、Pod的初始化1.4、Pod的运行及钩子函数1.4.1 k8s中的3种钩子函数1.4.2 k8s中的3种探测类型1.5、Pod的终止1.6、Pod的重启2、Pod的生命周期的五种状态(相位)💖The Begin💖点点关注,收藏不迷…

eclipse 如何创建python文件

一、准备 1.平台要求&#xff1a; 电脑除了要安装eclipse软件和Python语言包之外&#xff0c;还需要将Python集成到eclipse软件中&#xff0c;网上有很多的方法&#xff0c;这里就不细细介绍如何集成了。 在下面界面中可以看到自己已经安装了继承插件。具体方法见步骤2&…

YOLOV5 TensorRT部署 BatchedNMS(转换engine模型)(上)

文章目录 1.修改yolo detct层2.导出onnx模型并引入plugin3.转换为engine文件YoloV5使用tensorRT部署时,模型推理是放在cuda上操作,得到的结果需要在cpu上执行nms操作,但是当图像中的目标较多,或者检测出来的框较多时,nms耗时较长。 TensorRT 官方提供了batchedNMSPlugin的…

AI新篇章:全面解读ChatGPT3.5与GPT4.0的革命性融合

MidTool&#xff08;kk.zlrxjh.top&#xff09;&#xff0c;一个集成了多种先进人工智能技术的助手&#xff0c;融合了ChatGPT3.5、GPT4.0、DALLE 3和Midjourney等多个智能服务&#xff0c;提供多功能体验。下面是对这些技术的简要概述&#xff1a; **ChatGPT3.5**&#xff1a;…

可视化智慧工厂

在科技迅猛发展的今天&#xff0c;制造业正迎来一场深刻的变革——智慧工厂的崛起。可视化智慧工厂作为其中的重要一环&#xff0c;以其直观、高效、智能的特点&#xff0c;正成为制造业转型升级的关键所在。 一、什么是可视化智慧工厂? 传统的制造业生产方式往往依赖于人工…