目录

  • 一.前缀和
  • 二. 差分思想
    • 1.静态数组的区间求和问题
    • 2.静态维护区间加等差数列的求和问题
  • 三.二维前缀和
  • 二维前缀和例题P2280 [HNOI2003]激光炸弹
  • 四.例题
    • 例题一:差分+前缀和+贪心
    • 例题二.差分+前缀和

一.前缀和

给定一个序列,定义pre[i]=pre[i-1]+a[i];
可求区间[l,r]的和pre[r]-pre[l-1];
可求区间的[l,r]的异或和:(异或的逆运算是它本身)所以即为pre[r]^pre[l-1];

若有n组操作,操作为将区间[l,r]中的数增加k,最后输出这个数组。
可以暴力跑,但如果数据较大就会超时,所以要用到下面的差分思想。

二. 差分思想

差分:一个数列,如果知道第一个数,以及每一个数与前一个数的差值,那么我们就可以推出整个数列。先遍历一遍数组使a[i]=a[i]-a[i-1];让区间[l,r]里的数均+k就是让a[l]+=k;a[r+1]-=k;然后for(int i=1;i<=n;i++) a[i]+=a[i-1];即可还原数组

对于一个数组a定义数组s[i]=∑j=0ia[j]s[i]=\sum_{j=0}^{i}a[j]s[i]=∑j=0i​a[j]

a[j]为a数组的前缀和数组。

//为了避免数组越位,下标从1开始用
for(int i=1;i<=n;++i)
{s[i]=s[i-1]+a[i];
}

定义数组d[i]={a[i]if i=0a[i]−a[i−1]if i≥1d[i]=\begin{cases} a[i] & \text{ if } i=0 \\ a[i]-a[i-1] & \text{ if } i\geq1 \end{cases}d[i]={a[i]a[i]−a[i−1]​ if i=0 if i≥1​ 为a数组的差分数组。

//为了避免数组越位,下标从1开始用
for(int i=n;i;--i)    //倒着for的可以不借助两个数组,这里用d和a是为了看着清楚,实际可以用一个数组储存。
{d[i]=a[i]-a[i-1];
}

前缀和与差分运算为互逆运算,任意一个数组a的前缀和数组的差分数组是它本身。

1.静态数组的区间求和问题

静态数组的区间求和问题

2.静态维护区间加等差数列的求和问题

静态维护区间加等差数列的求和问题

三.二维前缀和

定义:pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j];
pre[i][j]表示的是(i,j)左下角的一个子矩形

类似容斥原理

(上面的这个图画错了,之前一直懒得改hhh过两天再复习到这儿的时候一定改)

二维前缀和例题P2280 [HNOI2003]激光炸弹

P2280 [HNOI2003]激光炸弹(二维前缀和的简单应用)难度⭐⭐⭐

四.例题

例题一:差分+前缀和+贪心

P3406 海底高铁
题目背景
大东亚海底隧道连接着厦门、新北、博艾、那霸、鹿儿岛等城市,横穿东海,耗资1000亿博艾元,历时15年,于公元2058年建成。凭借该隧道,从厦门可以乘坐火车直达台湾、博艾和日本,全程只需要4个小时。
题目描述
该铁路经过N个城市,每个城市都有一个站。不过,由于各个城市之间不能协调好,于是乘车每经过两个相邻的城市之间(方向不限),必须单独购买这一小段的车票。第i段铁路连接了城市i和城市i+1(1<=i<N)。如果搭乘的比较远,需要购买多张车票。第i段铁路购买纸质单程票需要Ai博艾元。
虽然一些事情没有协调好,各段铁路公司也为了方便乘客,推出了IC卡。对于第i段铁路,需要花Ci博艾元的工本费购买一张IC卡,然后乘坐这段铁路一次就只要Bi(Bi<Ai)元。IC卡可以提前购买,有钱就可以从网上买得到,而不需要亲自去对应的城市购买。工本费不能退,也不能购买车票。每张卡都可以充值任意数额。对于第i段铁路的IC卡,无法乘坐别的铁路的车。
Uim现在需要出差,要去M个城市,从城市P1出发分别按照P1,P2,P3…PM的顺序访问各个城市,可能会多次访问一个城市,且相邻访问的城市位置不一定相邻,而且不会是同一个城市。
现在他希望知道,出差结束后,至少会花掉多少的钱,包括购买纸质车票、买卡和充值的总费用。
输入格式
第一行两个整数,N,M。接下来一行,M个数字,表示Pi接下来N-1行,表示第i段铁路的Ai,Bi,Ci。
输出格式
一个整数,表示最少花费。
KKK的思路:对于其中一小段,我们要么全部买纸票,要么全部刷卡。
所以我们只需要统计每一小段经过的总次数。
如果你暴力模拟统计的话,估计会tle。
怎么快速知道每一段次数呢?
我们回忆一下“借教室”这道题。
如果你高兴的话,可以上线段树或者树装数组——但是没必要。
假设有5段,我们把1到3加上1,可以像图2一样,开头+1,结尾-1。然后2到4加1,如图3.

                  +1      -1          +1 +1   -1 -1- - - - -        --  - - -- -        -- -- - -- --1 2 3 4 5        1   2 3 4  5        1  2  3 4  5图1                   图2               图3

然后呢,我们求出每一项前缀和(就是从前往后加):

1 2 2 1 0
- - - - -
1 2 3 4 5图4

然后每一段直接贪心比较,然后就没有然后了

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
typedef long long ll;
ll n,m,ans,a[maxn],b[maxn],c[maxn],x,y,t[maxn],d[maxn];
int main()
{ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=1;i<=m;i++)cin>>d[i];for(int i=1;i<=n-1;i++)cin>>a[i]>>b[i]>>c[i];for(int i=1;i<=m-1;i++){x=min(d[i+1],d[i]);//左端点和右端点y=max(d[i+1],d[i]);t[x]++;t[y]--;//从1到4是经过了123,所以y已经是右端点+1了}for(int i=1;i<=n;i++)//前缀和t[i]+=t[i-1];for(int i=1;i<=n-1;i++)ans+=min(a[i]*t[i],b[i]*t[i]+c[i]);//贪心求最小花费cout<<ans<<endl;return 0;
}

例题二.差分+前缀和

题目链接
题目描述
HJ养了很多花(99999999999999999999999999999999999盆),并且喜欢把它们排成一排,编号0~99999999999999999999999999999999998,每天HJ都会给他的花浇水,但是他很奇怪,他会浇n(1 <= n <= 2 * 105)次水,每次都会选择一个区间[l, r],(0 <= l <= r <= 106),表示对区间[l, r]的花都浇一次水。现在问你,通过这些操作之后,被浇了i(1 <= i <= n)次水的花的盆数。
输入描述:
输入:第一行一个n,表示HJ的操作次数,接下来的n行,表示每一次选择的浇水区间。
输出描述:
输出:输出n个数字Cnt1, Cnt2……Cntn,(用空格隔开)Cnti表示被浇了i次水的花的盆数。
示例1
输入

3
0 3
1 3
3 8

输出

6 2 1

示例2
输入

3
1 3
2 4
5 7

输出

5 2 0

说明
对于样例1的图形解释被浇了1次的有:0, 4, 5, 6, 7, 8, cnt1 = 6
被浇了2次的有:1, 2. cnt2 = 2
被浇了3次的有: 3 . cnt3 = 3
思路:差分
等会再改

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6 + 7;
ll a[maxn];
ll sum[maxn];
int main()
{int n;while(cin>>n){memset(a,0,sizeof(a));memset(sum,0,sizeof(sum));for(int i=1;i<=n;i++){int x,y;scanf("%d%d",&x,&y);a[x]++,a[y+1]--;}ll a1=0;for(int i=0;i<=maxn;i++){a1+=a[i];sum[a1]++;}for(int i=1;i<=n;i++) printf("%lld ",sum[i]);puts("");}return 0;} 


注:如果您通过本文,有(qi)用(guai)的知识增加了,请您点个赞再离开,如果不嫌弃的话,点个关注再走吧,日更博主每天在线答疑 ! 当然,也非常欢迎您能在讨论区指出此文的不足处,作者会及时对文章加以修正 !如果有任何问题,欢迎评论,非常乐意为您解答!( •̀ ω •́ )✧

【算法】差分与前缀和 算法详解+例题剖析相关推荐

  1. 【树形DP】树形DP入门详解+例题剖析

    树形DP 树形DP准确的说是一种DP的思想,将DP建立在树状结构的基础上.整体的思路大致就是用树形的结构存储数据. 要学树形DP之前肯定是要先学会树和图的呀,至少先学会链式前向星,不会的话可以看一下我 ...

  2. 【基础算法】二分法(二分答案,二分查找),三分法,Dinkelbach算法,算法详解+例题剖析

    目录 一 . 二分法 二分搜索得要求: 二分查找步骤: 二分答案: 玄学的二分(二分答案) 二 . 三分法 例题 三.01分数规划问题相关算法与题目讲解(二分法与Dinkelbach算法) 一 . 二 ...

  3. 【数据结构】单调栈和单调队列 详解+例题剖析

    算法:单调栈和单调队列 一.单调栈和单调队列 二.单调栈例题 1.模板题入门 2.不懂不要急,看这道题 三.单调队列例题 1.入门 2.进阶 一.单调栈和单调队列 单调栈和单调队列与普通的栈,队列不同 ...

  4. 大白话解析Apriori算法python实现(含源代码详解)

    大白话解析Apriori算法python实现(含源代码详解) 一.专业名词解释 二.算法思路 三.python代码实现 四.Aprioir的优点.缺点及改进方法 本文为博主原创文章,转载请注明出处,并 ...

  5. JAVA中希尔排序去的讲解_java 中基本算法之希尔排序的实例详解

    java 中基本算法之希尔排序的实例详解 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shel ...

  6. EM算法(Expectation Maximization Algorithm)详解

    EM算法(Expectation Maximization Algorithm)详解 主要内容 EM算法简介 预备知识  极大似然估计 Jensen不等式 EM算法详解  问题描述 EM算法推导 EM ...

  7. 蓝桥杯 试题 算法训练 无聊的逗 C++ 详解

    题目: 逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中.不过他想到了一个游戏来使他更无聊.他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的 ...

  8. 蓝桥杯 试题 算法训练 无聊的逗 C++ 详解 - 未完善

    题目: 逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中.不过他想到了一个游戏来使他更无聊.他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的 ...

  9. 【JVM】对象存活判定算法、GC算法、STW、GC种类详解

    [JVM]对象存活判定算法.GC算法.STW.GC种类详解 文章目录 [JVM]对象存活判定算法.GC算法.STW.GC种类详解 GC主要关注的区域 垃圾标记阶段:对象存活判断 标记阶段:引用计数算法 ...

最新文章

  1. python五十二:__setattr__,__delattr__,__getattr__方法
  2. 深入了解softmax
  3. 【漫画】AI小猪的一生
  4. 设计模式(十一):从文Finder中认识组合模式(Composite Pattern)
  5. Socket编程实践(8) --Select-I/O复用
  6. string的find( )函数✅
  7. zw版【转发·台湾nvp系列Delphi例程】HALCON HighpassImage
  8. Atitit. Dwr 抛出异常error解决方案
  9. MyBatis之ResultMap简介,关联对象…
  10. mongodb 分片集群安装,以及环境准备
  11. echarts柱状图铺满_echarts 柱状图多种样式设置
  12. amazeui验证遇到的坑
  13. 服务器是计算机硬件嘛,什么是服务器,服务器是软件还是硬件?
  14. 偏门赚钱日赚1000,这个创业项目我本来不想说的....
  15. 密钥可以永久激活吗?
  16. SpringCloud(三):监控中心 hystrix turbine
  17. 【转】不花钱,自己查论文抄袭程度
  18. 英语语法2-一般过去时
  19. Linux jq 、vim以及LInux集群安装miniconda并配置虚拟环境(笔记)
  20. linux 查看硬盘报错_linux中挂载硬盘报错(you must specify the filesystem type)

热门文章

  1. 视觉SLAM如何基于深度学习闭环检测?
  2. Facebook开源高效图像Transformer,速度、准确率与泛化性能媲美SOTA CNN
  3. 人脸识别:insightface自定义数据集制作 | 附练手数据集
  4. OSChina 周日乱弹 —— 做一只舔狗,开心时就去舔她,不开心时就舔自己
  5. 如何修改系统时间显示格式
  6. 【UVALive 4642】Malfatti Circles(圆,二分)
  7. Redhat 中裸设备(raw) 的配置和oracle中使用
  8. ASP与ASP.NET的区别
  9. 巨潮网怎么下载年报_上海注册公司后如何下载电子营业执照
  10. java大整数类减1,自己写Java大整数《1》表示和加减