配套视频链接

https://www.bilibili.com/video/BV1xq4y1y7Kz

一、前缀和

1.1什么是前缀和

前缀和是一种重要的预处理,能大大降低查询的时间复杂度。常常用于一些题目的优化,其实前缀和是一种思想,主要是维护离线区间信息的一种优化手段

最简单的一道题就是给定 n 个数和 m 次询问,每次询问一段区间的和。求一个 O(n + m) 的做法。

1.2一维前缀和

1.2.1问题引出

例题:http://acm.mangata.ltd/p/P1501

1.2.2思路

对于一维前缀和我们在输入数据的时候就能进行处理,假设前缀和数组是pre,那么我们的pre[i] = pre[i-1]+a[i],这样就维护了一个前缀,注意的是这里的i从1开始遍历

代码示例:

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

这样我们就得到了一维前缀和的一个数组,那么这个数组可以干什么事呢?首先我们能在O(1)O(1)O(1)的时间复杂度内求出任一一个区间的和例如我们要求[L,R][L,R][L,R]区间和,即pre[R]-pre[L-1]

1.3一维前缀积

1.3.1问题引出

例题:https://ac.nowcoder.com/acm/contest/19483/A

1.3.2思路

由于有前缀和这种操作,我能能意识到这是一种思想,顺着这个思想我们能想到前缀积这个操作,和前缀和相似我们通过对pre数组进行乘法更新然后不断取模就能得到一个前缀积,如果我们想获得[L,R][L,R][L,R]的区间积那么需要用到逆元的操作即ans=pre[R]×inv(pre[L−1])ans = pre[R] \times inv(pre[L-1])ans=pre[R]×inv(pre[L−1])

代码示例:

pre[0] = 1;//否则全都变成0了
for(int i = 1;i <= n; ++i) {cin>>a[i];pre[i] = pre[i-1] * a[i] % mod;
}
求[L,R]区间内前缀积
ans = pre[R] * inv(pre[L-1]);

1.4 一维前缀异或

和上面类似,只不过维护的是异或和

1.5二维前缀和

1.5.1问题引出

例题:https://www.luogu.com.cn/problem/P2004

1.5.2思路

对于二维前缀和同理,我们从维护线前缀和变成了矩阵前缀和,换句话说就是从维护一维前缀和变成了维护二维前缀和。我们此时的pre[i][j]表示的含义就是从左上角[1][1]到右下角[i][j]这个矩阵的一个和,因此我们能写出这样一个维护代码pre[i][j]=pre[i−1][j]+pre[i][j−1]−pre[i−1][j−1]+a[i][j]pre[i][j]=pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1] + a[i][j]pre[i][j]=pre[i−1][j]+pre[i][j−1]−pre[i−1][j−1]+a[i][j],这个也是很好理解的,现在我们如果要求一个左上角为x1,y1x_1,y1x1​,y1,右下角为x2,y2x_2,y_2x2​,y2​的矩阵和就可以这样写:ans=pre[x2][y2]−pre[x2][y1−1]−pre[x1][y2−1]+pre[x1−1][y1−1]ans=pre[x2][y2]-pre[x2][y1-1]-pre[x1][y2-1]+pre[x1-1][y1-1]ans=pre[x2][y2]−pre[x2][y1−1]−pre[x1][y2−1]+pre[x1−1][y1−1]

我们可以来看这样一张图:

对于粉色部分就是我们想要求得的矩阵范围,对于黄色,和棕色部分就是我们多余的范围,需要减去,但是在减的过程中会遇到减的区间重复的情况,所以我们需要加上pre[x1−1][y1−1]pre[x1-1][y1-1]pre[x1−1][y1−1]的操作

代码实现:

for(int i = 1;i <= n; ++i) {for(int j = 1;j <= m; ++j) {cin>>a[i][j];pre[i][j] = pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1] + a[i][j];}
}
ans=pre[x2][y2]-pre[x2][y1-1]-pre[x1-1][y2]+pre[x1-1][y1-1];

1.5优缺点

优点很显然,就是能快速求出区间或者矩阵的一些信息例如和、积、异或等

缺点也很显然,就是不能在线操作,只能离线处理,遇到一个动态变化的就不能使用前缀和操作。

二、差分数组

2.1定义

对于已知有n个元素的离线数列d,我们可以建立记录它每项与前一项差值的差分数组fff:显然,f[1]=d[1]−0=d[1];f[1]=d[1]-0=d[1];f[1]=d[1]−0=d[1];对于整数i∈[2,n]i∈[2,n]i∈[2,n],我们让f[i]=d[i]−d[i−1]f[i]=d[i]-d[i-1]f[i]=d[i]−d[i−1]。

2.2性质

  • 计算数列各项的值:观察d[2]=f[1]+f[2]=d[1]+d[2]−d[1]=d[2]d[2]=f[1]+f[2]=d[1]+d[2]-d[1]=d[2]d[2]=f[1]+f[2]=d[1]+d[2]−d[1]=d[2]可知,数列第iii项的值是可以用差分数组的前iii项的和计算的,即d[i]=f[i]d[i]=f[i]d[i]=f[i]的前缀和。
  • 第iii项的前缀和即为数列前iii项的和

通过以上两点性质我们能在O(N)O(N)O(N)的时间复杂度内求出区间和以及每个位置的值,带来的好处就是能快速处理区间加减操作

2.3使用

对于区间[L,R][L,R][L,R]的增加一个x,那么在差分数组上我们进行的操作就是f[L]+x,f[R+1]−xf[L]+x,f[R+1]-xf[L]+x,f[R+1]−x,为什么呢?我们来回顾一下对于差分数组求前iii项前缀和求出来的就是d[i]d[i]d[i],那么我们在f[L]f[L]f[L]的位置进行一个加法操作也就是让从L这个位置开始的后面所有的d进行一个+x的操作,对于F[R+1]−xF[R+1]-xF[R+1]−x其实就是让R+1到后面所有元素减去x,因为前面在L这个位置进行了以后所有元素+x这个操作

这样一来区间修改再求单点的值或者区间值的话复杂度就是O(N)O(N)O(N)的,其实到后面我们会去学习一种数据结构->树状数组,我们利用差分这个性质的话,在O(logn)O(log_n)O(logn​)的时间复杂度就能求到单点和区间值,现在我们就不做探究了,其实差分重要的不是差分数组,而是差分思维

练习题单

洛谷题单:https://www.luogu.com.cn/training/200

牛客:https://ac.nowcoder.com/acm/contest/19483

牛客的BCD可能有点难,可以不用去做

蓝桥训练之前缀和与差分相关推荐

  1. 蓝桥杯JAVA-28.前缀和与差分详解

    个人博客 www.tothefor.com 蓝桥杯复习知识点汇总 目录 开始之前,推荐先看一下总结.再看内容.也许会帮你更好的理解. 前缀和是指某序列的前n项和,可以把它理解为数学上的数列的前n项和, ...

  2. 前缀和,差分算法训练

    知识点: 一维前缀和 二维前缀和 一维差分 二维差分 题目: 蓝桥杯2017初赛-k倍区间-前缀和 [蓝桥杯2018初赛]递增三元组-双指针,枚举,排序,前缀和

  3. 0x03.基本算法 — 前缀和与差分

    目录 一.前缀和 二.二维前缀和 1.二维前缀和的修改和求和 0. NOI 2003激光炸弹(二维前缀和) 1.牛妹吃豆子(二维前缀和模板,修改+求和) 2.静态数组的区间求和问题 3.静态维护区间加 ...

  4. 基本算法之前缀和与差分的是使用

    前缀和与差分 前缀和 鸣谢 二维前缀和 激光炸弹 差分 求差分 差分求区间修改 增减序列 最高的牛 前缀和 鸣谢 添加链接描述 和 添加链接描述 二维前缀和 激光炸弹 题目链接 解题思路: 解法思路: ...

  5. 前缀和与差分的使用(新手快速入门)

    前缀和 前缀和定义:s[0]=0; s[i]=s[i-1]+a[i]; 其中s[i]数组为a[i]数组的前缀和: 有了前缀和后,给定一个区间 [l,r] 的和就可以表示为: sum=s[r] -s[l ...

  6. 信奥中的数学:前缀和与差分、大整数开方技巧

    [算法2-1]前缀和与差分 [算法2-1]前缀和与差分 - 题单 - 洛谷 前缀和与差分 图文并茂 超详细整理(全网最通俗易懂) 前缀和与差分 图文并茂 超详细整理(全网最通俗易懂)_林深不见鹿 的博 ...

  7. 基本算法——前缀和与差分

    一.前缀和 一维前缀和 顾名思义,不再赘述. #include <iostream> #include <cstdio> #include <algorithm> ...

  8. c++算法基础必刷题目——前缀和与差分

    文章目录 前缀和与差分算法: 1.校门外的树 2.值周 3.中位数图 4.激光炸弹 5.二分 6.货仓选址 前缀和与差分算法:   前缀和与差分算法主要是为了快速求出某个区间的和,例如有一个数组a[1 ...

  9. 前缀和与差分——最大加权矩形

    前缀和与差分--最大加权矩形 题目描述 为了更好的备战 NOIP2013,电脑组的几个女孩子 LYQ,ZSC,ZHQ 认为,我们不光需要机房,我们还需要运动,于是就决定找校长申请一块电脑组的课余运动场 ...

最新文章

  1. [Head First设计模式]身边的设计模式——适配器模式
  2. matlab创建图形用户界面,Matlab 用户图形界面 基础 (一)
  3. 添加当前文件夹及其子文件夹到以及别而的文件夹到当前路径
  4. Python基础练习题:猜数字小游戏
  5. spring boot中data truncation data too long for column问题
  6. Erlang与java的内存架构比较
  7. Python2 之 print函数示例
  8. 分享一个关于网站适应性的解决方案
  9. 【请教】服务器上出现的两个问题!
  10. shell 数据类型
  11. android开发app初始化,Android 的 Application 初始化
  12. AndroidDeveloper Weekly No.5
  13. FISCO BCOS源码(5)基本概念
  14. java过滤空号了停机号_手机空号、停机、注销,空号检测为你去除无效号码
  15. erphpdown9.2.7前台会员中心美化模板
  16. wifi情况下使用fiddler_如何对手机http进行抓包?Fiddler工具超好用
  17. PCA与2DPCA及2D-2DPCA零基础理解(下)
  18. linux mysql搭建禅道详细教程_2019-08-28 redhat linux如何部署禅道服务器(一键安装包)...
  19. hdu6608 Fansblog(威尔逊定理)
  20. 阿里的互联网三高架构是真的牛!腾讯百度根本模仿不来

热门文章

  1. Matlab二维曲线之fplot函数
  2. hibernate.validator验证参数
  3. C#Const与static readonly的区别
  4. vue双向数据绑定的简单实现
  5. java 读CSV 和 Excel
  6. Java中导入Excel文件
  7. 计算机网络总结 第一章 计算机网络概论
  8. 从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)
  9. ERROR: ld.so: object '/usr/lib64/libtcmalloc.so.4' from LD_PRELOAD cannot be preloaded: ignored
  10. 计算机组成一简化模型