差分算法(蓝桥杯复习+例题讲解+模板c++)
文章目录
- 差分介绍
- 差分应用
- 区间加
- 区间求和
- 总结
- 3729. 改变数组元素
- 100. 增减序列
文章首发于:My Blog 欢迎大佬们前来逛逛
差分介绍
差分是一种常见的算法,用于快速修改数组中某一段区间的值。
差分的思想就是预处理出数组的差分数组,然后修改区间时,只需要修改两个位置的值,即可快速完成区间修改。最后再通过差分数组求出原数组。 差分数组 did_idi 表示原数组中相邻两个元素之间的差值,即 di=ai−ai−1d_i=a_i-a_{i-1}di=ai−ai−1,其中 aia_iai 表示原数组中第 iii 个元素的值。则对于区间 [l,r][l,r][l,r] 的加上 kkk 的操作,可以表示为: dl=dl+k,dr+1=dr+1−kd_l=d_l+k,\quad d_{r+1}=d_{r+1}-kdl=dl+k,dr+1=dr+1−k 这样就完成了区间加 kkk 的操作。最后只需要用差分数组求出原数组即可。 ai=∑j=1idja_i=\sum_{j=1}^{i} d_jai=j=1∑idj
差分应用
区间加
以区间加为例,设 aia_iai 表示原数组中第 iii 个元素的值,did_idi 表示差分数组中第 iii 个元素的值,则对于区间 [l,r][l,r][l,r] 的加上 kkk 的操作,可以表示为: dl=dl+k,dr+1=dr+1−kd_l=d_l+k,\quad d_{r+1}=d_{r+1}-kdl=dl+k,dr+1=dr+1−k 最后只需要用差分数组求出原数组即可: ai=∑j=1idja_i=\sum_{j=1}^{i} d_jai=j=1∑idj 以下是区间加的代码实现:
vector<int> a; // 原数组
vector<int> d(a.size(), 0); // 差分数组
// 区间加 k
int l = 2, r = 5, k = 3;
d[l] += k;
d[r+1] -= k;
// 求出原数组
for (int i = 1; i < a.size(); i++) {d[i] += d[i-1];
}
区间求和
另一种常见的操作是区间求和。设 aia_iai 表示原数组中第 iii 个元素的值,did_idi 表示差分数组中第 iii 个元素的值,则对于区间 [l,r][l,r][l,r] 的求和操作,可以表示为: ∑i=lrai=∑i=lr(∑j=1idj)=∑j=1rdj−∑j=1l−1dj\sum_{i=l}^{r} a_i = \sum_{i=l}^{r} (\sum_{j=1}^{i} d_j) = \sum_{j=1}^{r} d_j - \sum_{j=1}^{l-1} d_ji=l∑rai=i=l∑r(j=1∑idj)=j=1∑rdj−j=1∑l−1dj 这样就能用差分数组快速求出区间和了。 以下是区间求和的代码实现:
cppCopy codevector<int> a; // 原数组
vector<int> d(a.size(), 0); // 差分数组
// 区间加 k
int l = 2, r = 5, k = 3;
d[l] += k;
d[r+1] -= k;
// 求出原数组
for (int i = 1; i < a.size(); i++) {d[i] += d[i-1];
}
// 区间求和
l = 3, r = 7;
int ans = d[r] - d[l-1];
总结
差分是一种常见的算法,用于快速修改数组中某一段区间的值。差分的思想就是预处理出数组的差分数组,然后修改区间时,只需要修改两个位置的值,即可快速完成区间修改。最后再通过差分数组求出原数组。差分算法在区间加、区间求和等问题中都有广泛的应用。
3729. 改变数组元素
3729. 改变数组元素
题目要求:初始给你一个全为0的序列,给你一组数据,其中每一个数组a[i]=n表示对自 i 开始的的前面n个元素全都都变为1,已经是1的不予理会,求得操作完成后的数列的值。
示例:
6
0 3 0 0 1 3
操作后:
1 1 0 1 1 1
对于【2】位置,它的值为3,意味着自位置 2开始,前3个元素全部都变为1,则:
差分数组:[0]=1,[3]=-1。
我们根据差分数组转换为原数组:1到3的元素就是 1 1 0,这样我们就成功的利用差分数组改变了原数组的值。
因此对于每一个位置的值,我们对差分进行操作,b[l]+=1,b[r]-=1,最后利用差分数组转换为原数组。
注意几个地方:
- 如果根据所给的值得到对差分数组操作的 l 与r? 假设我们的值为x,则左端点为 i-x+1,右端点为 i
- x必须取 i 和 x 的最小者,原因是即使 x大于i,则 i-x会得到一个负值,我们使得x=i,那么这样的话就是默认左端点为1开始
- 只需对差分数组进行操作:b[l]+=1,b[r]-=1
- 根据差分数组反推出原数组
- 我们只需要得到每一个位置的值是0还是1即可,对于原数组我们根据其值进行两次 !!的操作,这个操作可以使得 0值仍然是0值,任意非零值都是1
- 注意清空差分数组的元素值。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
using namespace std;
const int N=2e5+10;
int nums[N],b[N];
int t,n;
int main(){cin>>t;while (t--){cin>>n;memset(b,0,(n+1)*4);for (int i=1;i<=n;i++){int x;cin>>x;x=min(x,i);int l=i-x+1,r=i;b[l]+=1;b[r+1]-=1;}for (int i=1;i<=n;i++){b[i]+=b[i-1];}for (int i=1;i<=n;i++){cout<<!!b[i]<<' ';}cout<<endl;}return 0;
}
100. 增减序列
100. 增减序列 - AcWing题库
题目要求:每次对某个区间进行操作可以选择整体加1,或者整体减1,使得整个数列的值全部相等,求得最少操作次数与最少操作次数对应的整个数列值的不同方案。
4
1 1 2 2
操作后得:
1 1 1 1
2 2 2 2
-----
0 0 0 0 //非最少操作次数,因此不计
最少操作次数为2,即我们把 1到2的1整体加1,即可得到全部为2;把3到4的2整体减1,可以得到全部为1,这两种操作的最少操作次数都是1次,对应的方案数有两种
如果我们要想把全部的数列的值都变为唯一的值,则它对应的差分数组的值一定是:
num 0 0 0 0...
即b[1]=num,往后每一个 b的值都为0,这样我们就得到了一个全部值都相同的原数组。
因此我们该如何构造一个这样的差分数组呢?
- 只有首元素不为零
- 差分数组中 2到n的全部元素都为0
可以发现:
-
最少操作次数:把差分数组变为上面的情况的最少操作次数
-
对应的方案数:因此就是求 b[1] 有多少种方案,就是数列中不同的值的种类
则在区间【2,n】中:
由于差分数组中值有正有负,因此我们根据贪心的思路:
每次选择两个符号不同的数值,一个加1,一个减1,这样就能用最少的次数将正负两个符号不同的数字相消
我们规定pos为差分数组中所有正数的和,neg为所有负数的绝对值的和。
则min(pos,neg)就是正数与负数进行相消的方案数,然后使得数列中所有的值都是相同符号:
假设差分数组为:
2 5 -2 3 -1
pos=8,neg=3,则我们经过 min(8,3)=3,即经过了三次操作使得所有的负数都消失:
2 3 0 2 0 (两个负数一个加2,一个加1,对应其他位置一个减2,一个减1)
然后我们得到了全部都是符号相同的序列,下一步我们就是把【2,n】中所有的符号相同的数相消,使得数列中只留下【1】位置的值,则对于【2,n】中的数字可以有两种方案进行相消:
- 与【1】位置的值进行相消,此时会改变【1】的值
- 与【n+1】位置的值进行相消,此时不会改变【1】的值,【n+1】位置的值无意义。
因此我们再经过 |pos-neg|次操作使得所有的【2,n】位置的元素全部变为0,对于最少操作次数,选择两种方案都是一样的,因此最少操作次数为:min(pos,neg)+abs(pos-neg)
如果要统计对应的最少操作次数的方案数:则一定是 |pos-neg|+1。
上面相同符号进行相消配对的时候,选择 |pos-neg| 个与[1]匹配,则[1]改变,可以造成|pos-neg|个[1]的不同情况;另外选择[n+1],则[1]不变,可以造成1种[1]的情况。
因此最终的组合数就是 |pos-neg|+1
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
using namespace std;
#define int long long
const int N=1e5+10;
int nums[N];
int n;
signed main(){cin>>n;for (int i=1;i<=n;i++){cin>>nums[i];}for (int i=n;i>1;i--){nums[i]-=nums[i-1];}int pos=0,neg=0;for (int i=2;i<=n;i++){if (nums[i]>0) pos+=nums[i];else neg-=nums[i];}cout<<min(pos,neg)+abs(pos-neg)<<endl;cout<<abs(pos-neg)+1<<endl;return 0;
}
相关文章:
差分算法(蓝桥杯复习+例题讲解+模板c++)
文章目录差分介绍差分应用区间加区间求和总结3729. 改变数组元素100. 增减序列文章首发于:My Blog 欢迎大佬们前来逛逛 差分介绍 差分是一种常见的算法,用于快速修改数组中某一段区间的值。 差分的思想就是预处理出数组的差分数组,然后修改…...
CSS+ JS 实现手电筒效果
前言概述 JavaScript 结合 CSS 打造的一款图片特效,当鼠标拖拽滑块时,让本该置灰的图片局部恢复本来的颜色。且该效果随着你的鼠标的按下时的移动而移动。 核心功能 图片置灰 拖拽功能 让滑块位置处的图片恢复本来的颜色 实现原理 这个的实现原理并不…...
2021地理设计组二等奖:基于InSAR和指数分析的地面沉降风
作品简介 一、作品背景 地面沉降是指地面高程的降低, 又称地面下沉或地沉, 是以缓慢、难以察觉的向下垂直运动为主, 是指在自然和人为因素作用下, 由于地壳表层土体压缩而导致区域性地面标高降低的一种环境现象。目前, 地面沉降己成为城市化进程中普遍存在的生态环境问题, 成为…...
计算机操作系统(第四版)第二章进程的描述与控制—课后习题答案
1.什么是前趋图?为什么要引入前趋图? 前趋图是一个有向无循环图,记为DAG,用于描述进程之间执行的先后关系。 2.试画出下面四条语句的前趋图: S1:axy; S2:bz1; S3:ca-b; S4:wc1; 3.为什么程序并发执行会产生间断性特征&…...
CAN通信----电路图
CAN通信----基本原理 一、CAN总线网络连接 1.闭环总线网络----ISO11898 闭环总线网络高速、短距离,它的总线最大长度为 40m,通信速度最高为 1Mbps,总线的两端各要求有一个120 欧的电阻。 2.开环总线网络----ISO11519 开环总线网络低速、…...
Windows系统安装ElasticSearch(一)
一 ES介绍Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单,它不仅包括了全文搜索功能,还可以进行以下工作:分布式实时文件存储&#…...
linux 产生随机数 并遍历
1、产生随机数 varRANDOMvarRANDOM varRANDOMvar[ $var % 150 ] 2、产生不重复的随机数 $ entries($(shuf -i 0-149 -n 15)) $ echo “${entries[]}” 3、对随机数排序 $ entries($(shuf -i 0-149 -n 15 | sort -n)) $ echo “entries[]"12224549546678798393118119124140…...
【3.24】Mybatis常见面试题
Mybatis常见面试题 #{}和¥{}的区别是什么? 【#】:底层执行SQL使用PreparedStatement对象,预编译SQL,相对安全。入参使用占位符的方式。 【$】:底层执行SQL使用Statement对象,入参使用SQL拼接的…...
IDEA 热部署,修改代码不用重启项目
热部署指在修改项目代码的时候不重启服务器让修改生效。安装JRebel and XRebelFile->Settings,然后Plugins-> Marketplace,输入JRebel,安装如下插件——JRebel and XRebel ,重启idea激活JRebel and XRebel第一行输入网址&am…...
将 XLS 转换为 EXE:xlCompiler Crack
只需单击几下即可将Excel文件转换为应用程序 xl编译器无需编程即可将您的Excel电子表格转换为软件应用程序 将 XLS 转换为 EXE 将Excel文件转换为具有保护选项的应用程序。Excel 到 EXE 转换器为您提供了分发 Excel 模型的竞争优势和灵活性。将 Excel 的功能丰富的环境保存在应…...
【百面成神】spring基础12问,你能坚持到第几问
前 言 🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端 ☕专栏简介:java面试宝典,特点:全、精、深、简,力求每个核心知识点1分钟回答好。 dz…...
javaSE类和对象(下)
目录君1.封装2.访问限定符3.包的定义及使用4.static成员变量5.static成员方法6.代码块及其分类实例代码块静态代码块静态代码块与实例代码块的执行顺序static成员变量(类变量)初始化1.封装 面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要…...
【数据结构】第四站:单链表力扣题(二)
目录 一、链表的回文结构 二、相交链表 三、环形链表 四、环形链表Ⅱ 五、复制带随机指针的链表 一、链表的回文结构 题目描述:链表的回文结构_牛客题霸_牛客网 对于这道题,如果没有前面的一些题的基础,是非常难做的,我们的思…...
KafKa知识汇总
前言 汇总相关知识 Kafka快速实战与基本原理详解...
【RV1126】调试GT911,1024x600 7寸 MIPI 电容触摸屏
文章目录一、驱动注册失败二、触摸屏可以触摸,但是x轴数据反了三、可以触摸了,但是Y轴数据跳变,几乎只有一半的屏幕是可以正常滑动的三、汇顶触摸屏配置文件解析四、使用新的配置文件4.1 新配置解决问题4.2 测试触摸的方法在kernel增加frame …...
C的强符号/弱符号
首先上代码和结果: 代码: #include <stdio.h> int k; int k; int main() {printf("addr of k %p\n", &k);printf("value of k %d\n", k);return 0; }结果: addr of k 00408074 value of k 0问题&…...
AD/DA转换(XPT2046)
AD/DA介绍AD(Analog to Digital):模拟-数字转换,将模拟信号转换为计算机可操作的数字信号DA(Digital to Analog):数字-模拟转换,将计算机输出的数字信号转换为模拟信号AD/DA转换打开…...
乐观锁和悲观锁 面试题
Mysql的乐观锁和悲观锁 实现方式加锁时机常见的调用方式优势不足适用场景乐观锁开发自定义更新数据的时候sql语句中进行version的判断高并发容易出现不一致的问题高并发读,少写悲观锁Mysql内置查询数据的开始select * for update保证一致性低并发互联网高并发场景极…...
【Autoware规控】mpc_follower模型预测控制节点
文章目录1. 技术原理2. 代码实现1. 技术原理 MPC,即Model Predictive Control(模型预测控制),是一种基于动态模型的控制算法。MPC算法通过建立系统的数学模型,根据当前状态和一定时间内的预测,优化未来的控…...
成果VR虚拟3D展厅让内容更丰富饱满
随着数字技术的不断发展和普及,数字化展厅成为了一种重要的展示形式。线上虚拟展厅作为数字化展示的一种新形式,采用虚拟现实技术,能够克服时空限制,打破传统展览业的展示模式,为用户提供更加丰富、立体、沉浸式的展览…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
