当前位置: 首页 > news >正文

【一维 前缀和+差分】

一、一维前缀和

1.1 定义

给定一个数组 a[1..n],其前缀和数组 pre[1..n] 定义为:

pre[i]=a[1]+a[2]+⋯+a[i] pre[i] = a[1] + a[2] + \dots + a[i] pre[i]=a[1]+a[2]++a[i]

pre[i] 表示原数组从第 1 项到第 i 项的和。

1.2 构建

int a[N], pre[N];
for (int i = 1; i <= n; i++) 
{pre[i] = pre[i - 1] + a[i];
}

1.3 区间求和

使用前缀和可以在 O(1)O(1)O(1) 时间内求任意区间 [l,r][l, r][l,r] 的和:

sum=pre[r]−pre[l−1] sum = pre[r] - pre[l - 1] sum=pre[r]pre[l1]

1.4 应用场景

  • 快速计算区间和
  • 优化暴力 O(n2)O(n^2)O(n2) 的区间统计问题为 O(n)O(n)O(n)

1.5 示例

// 输入一个数组,求多个区间 [l, r] 的和
int a[N], pre[N];
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) pre[i] = pre[i - 1] + a[i];while (q--) 
{int l, r;cin >> l >> r;cout << pre[r] - pre[l - 1] << '\n';
}

二、一维差分数组

2.1 定义

对于原数组 a[1..n],其差分数组 diff[1..n] 定义为:

diff[i]=a[i]−a[i−1]  (i≥2),  diff[1]=a[1] diff[i] = a[i] - a[i - 1]\ \ (i \geq 2),\ \ diff[1] = a[1] diff[i]=a[i]a[i1]  (i2),  diff[1]=a[1]

通过差分数组可以快速实现对一个区间 [l,r][l, r][l,r] 的所有值同时加上一个数 ddd

2.2 构建

int a[N], diff[N];
diff[1] = a[1];
for (int i = 2; i <= n; i++) 
{diff[i] = a[i] - a[i - 1];
}

2.3 区间加法操作

若想对区间 [l,r][l, r][l,r] 所有数加上 ddd,只需:

diff[l] += d;
diff[r + 1] -= d;

原理在于:差分数组记录的是“增量”,只需要在区间起点加一个数、在区间终点的下一位减去这个数,就能确保中间所有位置都累加这个值。

然后通过前缀和还原整个数组:

a[1] = diff[1];
for (int i = 2; i <= n; i++) 
{a[i] = a[i - 1] + diff[i];
}

2.4 区间减法操作

若想对区间 [l,r][l, r][l,r] 所有数减去 ddd,也可以使用差分数组:

diff[l] -= d;
diff[r + 1] += d;

原理类似:差分数组记录的是“增量”,如果我们想对一个区间 [l,r][l, r][l,r] 的所有元素减去 ddd,只需要在区间起点加上 −d-dd,在区间终点的下一位加上 +d+d+d,就能确保整个区间内的值都减少 ddd,而其他位置不受影响。这与区间加法操作完全对称,只是将 ddd 替换为 −d-dd

2.5 应用场景

  • 多次区间加操作(比树状数组/线段树更快)
  • 多次构造某种“影响”或“变化”的模型(如教室占用、涨价、染色)

2.6 示例

// 初始数组为 0,对多个区间加值,输出最终数组
int diff[N] = {0};
cin >> n >> m; // n 个元素,m 次操作
for (int i = 1; i <= m; i++) 
{int l, r, d;cin >> l >> r >> d;diff[l] += d;diff[r + 1] -= d;
}// 还原结果数组
int a[N];
a[0] = 0;
for (int i = 1; i <= n; i++) 
{a[i] = a[i - 1] + diff[i];cout << a[i] << ' ';
}

三、前缀和 vs 差分数组

技术优势典型操作使用时机
前缀和快速区间求和查询 [l,r][l,r][l,r] 区间和多次查区间和
差分数组快速区间加区间加 ddd ororor −d-dd多次改区间数值

它们两个往往成对出现,比如:

  • 差分数组批量处理区间修改
  • 再通过前缀和恢复最终值

四、常见问题汇总

  1. 差分数组的还原为什么用前缀和?

    差分数组记录的是相邻元素之间的增量,所以前缀和就是原数组。

  2. 差分数组是否支持区间乘法?

    不支持,差分只能处理区间加减。

  3. 差分数组是否可以从 0 开始?

    可以,但要注意下标对应的意义,最好从 1 开始更清晰。

  4. 是否每次都需要重建差分数组?

    看情况。如果每次操作互不干扰,可以复用;否则建议重建或静态开数组并清空。


五、总结

  • 前缀和用于高效区间查询
  • 差分数组用于高效区间修改
  • 两者配合使用是处理“区间加减 + 查询”类问题的利器

在处理数据量较大的题目(如 10510^510510610^6106)时,前缀和与差分是比线段树更快、更简洁的选择。

http://www.xdnf.cn/news/1121383.html

相关文章:

  • ether.js—6—contractFactory以部署ERC20代币标准为例子
  • CSS手写题
  • 详解彩信 SMIL规范
  • Leaflet面试题及答案(81-100)
  • 代码随想录day34dp2
  • ARMv8.1原子操作指令(ll_sc/lse)
  • 苍穹外卖学习指南(java的一个项目)(老师能运行,但你不行,看这里!!)
  • python的微竞网咖管理系统
  • UI前端与数字孪生结合实践探索:智慧物流的仓储自动化管理系统
  • Java文件操作
  • Reactor 模式详解
  • 【Echarts】 电影票房汇总实时数据横向柱状图比图
  • ubuntu 22.04 anaconda comfyui安装
  • libimagequant windows 编译
  • 云手机常见问题解析:解决延迟、掉线等困扰
  • 机器学习中的朴素贝叶斯(Naive Bayes)模型
  • 新型eSIM攻击技术可克隆用户资料并劫持手机身份
  • Android 16系统源码_窗口动画(一)窗口过渡动画层级图分析
  • 在 Azure Linux 上安装 RustFS
  • 如何保护文件传输安全?文件传输加密
  • 实战:如何创建 AWS RDS 数据库
  • 从“有”到“优”:iPaaS 赋能企业 API 服务治理建设
  • Foundry 私钥管理指南:方法与安全最佳实践
  • 上下文管理器 和 contextlib 模块
  • 深入浅出Kafka Producer源码解析:架构设计与编码艺术
  • VMware 虚拟机装 Linux Centos 7.9 保姆级教程(附资源包)
  • mybatis-plus-jpa-support
  • 常用的OTP语音芯片有哪些?
  • Spring Boot启动原理:从main方法到内嵌Tomcat的全过程
  • Linux 系统下的 Sangfor VDI 客户端安装与登录完全攻略 (CentOS、Ubuntu、麒麟全线通用)