【差分数组】

差分数组不仅仅是一个优秀的线性结构,还是一种很好的思想,其主要用于修改区间、查询单点,其中,修改区间的时间复杂度均为 O(1),查询单点的时间复杂度为 O(n)

对于已知有 n 个元素的离线数列 a,可以建立一个记录它每项与前一项差值的差分数组 f[],那么显然有:

  • f[1]=a[1]-0=a[1]
  • f[i]=a[i]-a[i-1]

计算数列各项的值,可以发现:

  • a[2]=f[1]+f[2]=a[1]+(a[2]-a[1])=a[2]
  • a[3]=f[1]+f[2]+f[3]=a[1]+(a[2]-a[1])+(a[3]-a[2])=a[3]
  • a[4]=f[1]+f[2]+f[3]+f[4]=a[1]+(a[2]-a[1])+(a[3]-a[2])+(a[4]-a[3])=a[4]
  • ...

以此类推,可以发现数列 a 的第 i 项是可以用差分数组前 i 项和来计算的,即:a[i]=f[i] 的前缀和

计算数量每一项的前缀和,那么有:

即:可用差分数组来求出数列的前缀和

int a[N];
int f[N],sum[N];
void init(){f[1]=a[1];for(int i=2;i<=n;i++)//差分数组f[i]=a[i]-a[i-1];for(int i=1;i<=n;i++)//前缀和sum[i]=sum[i-1]+a[i];
}

【差分数组用途】

1.快速处理区间加减

假如现在要对数列区间 [L,R] 上的每个数都加上 x,那么通过 a[i]=f[i] 的前缀和 的性质可以知道:

  • 第一个受影响的差分数组中的元素为 f[L],所以令 f[L]+=x,那么后面数列元素在计算过程中都会加上 x
  • 最后一个受影响的差分数组中的元素为 f[R],所以令 f[R+1]-=x,那么可以保证不会影响到 R 以后数列元素的计算

这样一来,就不必对区间内每一个数进行处理,只需处理两个差分后的数即可

void add(int L,int R,int x){f[L]+=x;f[R+1]-=x;
}
void sub(int L,int R,int x){f[L]-=x;f[R+1]+=x;
}

2.查询单点

根据差分数组的性质,差分数组第 i 项的前缀和即为序列的第 i 项,因此可利用差分数组来计算原序列第 x 个点的值

int query(int x){int sum=0;for(int i=1;i<=x;i++)sum+=f[i];return sum;
}

【模版】

int n,m;
int a[N];
int f[N],sum[N];
void init(){//求差分数组f[1]=a[1];for(int i=2;i<=n;i++)//差分数组f[i]=a[i]-a[i-1];
}
void add(int L,int R,int x){//区间[L,R]全部加上xf[L]+=x;f[R+1]-=x;
}
void sub(int L,int R,int x){//区间[L,R]全部减去xf[L]-=x;f[R+1]+=x;
}
void query(int x){//查询序列第i项int sum=0;for(int i=1;i<=x;i++)sum+=f[i];return sum;
}
int main(){cin>>n>>m;for(int i=1;i<=n;i++)//输入序列cin>>a[i];init();//计算差分数组while(m--){//m个操作char op;cin>>op;if(op=='A'){//加操作int l,r,x;cin>>l>>r>>x;add(l,r,x);}else if(op=='S'){//减操作int l,r,x;cin>>l>>r>>x;sub(l,r,x);}else if(op=='Q'){//查询操作int x;cin>>x;cout<<query(x)<<endl;}}return 0;
}

【例题】

  1. Color the ball(HDU-1556)(单点查询):点击这里
  2. 借教室(洛谷-P1083)(差分数组+二分):点击这里

线性结构 —— 差分数组相关推荐

  1. c语言实现线性结构(数组与链表)

    由于这两天看了数据结构,所以又把大学所学的c语言和指针"挂"起来了. 本人菜鸟一枚请多多指教.下面是我这两天学习的成果(数组和链表的实现,用的是c语言哦!哈哈). (一)数组的实现 ...

  2. 线性结构(顺序存储和链式存储)和非线性结构的特点及区别

    1. 线性结构 特点:除第一个元素只有一个"后继"和最后一个元素只有一个"前驱",其它每个元素只有一个"前驱"元素和一个"后继&q ...

  3. java中线性结构的例子_java数据结构--线性结构

    一.数据结构 数据结构由数据和结构两部分组成,就是将数据按照一定的结构组合起来,这样不同的组合方式有不同的效率,可根据需求选择不同的结构应用在相应在场景.数据结构大致 分为两类:线性结构(如数组,链表 ...

  4. java算法概述,Java数据结构与算法基础(一)概述与线性结构

    Java数据结构与算法基础(二)递归算法 Java数据结构与算法基础(一)概述与线性结构 学习目的:为了能更顺畅的读很多底层API代码和拓宽解决问题的思路 一.数据结构概述 1.数据结构是什么?数据与 ...

  5. 数据结构一 线性结构和非线性结构

    暑假到来,由于自己之前确实数据结构学的一般,因此决定重新学习一下数据结构,一是加深理解,二是对算法使用java进行测验,增强实践能力,主要是通过尚硅谷的视频进行学习,写上去的笔记,有些是尚硅谷的内容, ...

  6. 线性结构 -- 连续存储(数组), 1个简单的c语言代码实现.

    数据结构大体成上可以分成两种: 1. 线性结构. 2. 非线性结构( 树,图) 1. 什么是线性结构        大概上可以这样定义: 加入所有的节点可以用一条直线连接起来. 就是线性结构... 2 ...

  7. 【数据结构总结】第四章:串、数组和广义表(线性结构)

    第四章:串.数组和广义表(线性结构) 提示:本文主要是以思维导图的形式概括数据结构第一章的精华内容,基本不会用到文字性的内容,目的是为了给大家梳理每个重要的知识点的相关概念,方便大家在复盘的时候快速阅 ...

  8. 线性结构-前缀和和差分

    主要内容: [概述] [一维前缀和] [二维前缀和] [例题] [差分数组]

  9. 计算机考试 什么链,啥数组、链表、线性结构?计算机二级office选择题必考串讲2-2...

    我是女神二级的叶子老师,用自己多年的计算机教师经验,把最容易吸收的知识点分享给考生.我将持续分享关于计算机二级国考方面的文章.感兴趣的读者请点击右上角"关注"吧! 公共基础 二级O ...

最新文章

  1. 在Windows和Linux上编译gRPC源码操作步骤(C++)
  2. JWT 应该保存在哪里?
  3. 多路I/O转接服务器——epoll
  4. Linux有趣指令(一)
  5. MySQL数据库模式(SQL_MODE)中的STRICT_TRANS_TABLES和STRICT_ALL_TABLES
  6. mysql 检查列是否存在,如何检查mysql表列是否存在?
  7. 前端页面数据埋点、分析和参考
  8. 对象测试_心理测试:你会选择跟对象去吃什么夜宵?测你治愈失恋的方法是什么...
  9. Linux怎么查看编译ARM平台程序的编译器arm-linux-gcc
  10. unity html get post,使用C#开发HTTP服务器系列之实现Get和Post
  11. 图片完整检查linux,Linux 下的免费图片查看器
  12. SQL笔记(约束、外键、casewhen)
  13. matlab中subs赋值范围,[转载]Matlab的accumarray(subs, val) 解释
  14. Nature:分离到一种位于原核生物-真核生物“交界”的古菌
  15. Mockplus Cloud updated传达设计意图的新方法
  16. 2018科大讯飞Java笔试第三道编程题
  17. Oblique Frustum Clipping
  18. 修改完bug GIT的提交流程 及NVM的常用指令
  19. 20201022-成信大-C语言程序设计-20201学期《C语言程序设计B》C-trainingExercises03
  20. 干货 | 携程微信小程序如何进行Size治理

热门文章

  1. 最新!2001-2021武书连中国大学排行榜Top 20
  2. 重磅!阿里宣布成立芯片公司,“平头哥”能解决中国的“无芯之痛”吗?
  3. STM32之串口例程
  4. 华为鸿蒙osbeta,久等了!华为鸿蒙OS 2.0测试版推送,上手体验到底如何?
  5. 服务器报告它来自digest_【关注】服务器行业现状研究
  6. Linux基本操作——VI和VIM
  7. 重构 - 美股行情系统APP推送改造
  8. 拖拽报表设计香不香—JimuReport 1.4.0新特性
  9. error: couldn't connect to server 127.0.0.1:27017 src/mongo/shell/mongo.js
  10. iBATIS sql中的处理特殊符号的做法