C/C++ 前缀和与差分

个人主页:仍有未知等待探索_C语言疑难,数据结构,算法-CSDN博客

专题分栏:算法_仍有未知等待探索的博客-CSDN博客

目录

一、前言

1、什么是前缀和

2、什么是差分

3、优势

1.朴素做法:

2.用差分数组

二、代码实现

1、给一个数组去求其差分数组

2、给一个数组去求其前缀和数组


一、前言

1、什么是前缀和

前缀和是一种预处理,用于降低查询时的时间复杂度。其就像是数学中的前n项和。

给定 n个整数,然后进行 m 次询问,每次询问求一个区间内值的和。

如果用暴力写法,那每次询问都需要从区间左端点循环到区间右端点求和,时间复杂度较大。

这种时候就可以预先求出该数组的一维前缀和。

比如说数组【1,1,1,1,1】,则前缀和数组就是【1,2,3,4,5】。

2、什么是差分

差分更像是前缀和数组的原数组。

比如说前缀和数组是【1,2,3,4,5】,则差分数组就是【1,1,1,1,1】。

总结一句话:前缀和和差分是互逆运算。

3、优势

如果让你把数组的一个子区间全都加上一个数 c,并且去对改区间进行求和。

1.朴素做法:

  • 找到该区间,然后对每个数进行相加 c
  • 在遍历一遍进行求和

如果要加数的区间多,求和的区间多的话,时间太长。

2.用差分数组

  • 找到要加数的区间左端点,然后仅对左端点进行加 c 操作(在左端点的右侧,其前缀和数组均加上了 c)
  • 但是我们想加数的范围仅在某一个区间,这样的话我们就对其右端点+1进行-c操作,这样就行了

二、代码实现

注意:数组一定要从1开始进行存储,要不然求前缀和数组的时候还要特判。

1、给一个数组去求其差分数组

#include<iostream>
using namespace std;

const int N = 1e5 + 5;
int a[N];//原数组
int b[N];//差分数组
int n;//数的个数

//可以将求一个差分数组,分成求1个元素的差分数组
void insert (int c,int i)
{
	b[i] += c;
	b[i + 1] -= c;
}
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];

	for (int i = 1; i <= n; i++) insert(a[i], i);

	for (int i = 1; i <= n; i++) cout << b[i] << " ";
	return 0;
}

2、给一个数组去求其前缀和数组

#include<iostream>
using namespace std;

const int N = 1e5 + 5;
int n;//数的个数
int a[N];//原数组
int s[N];//前缀和数组

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

	for (int i = 1; i <= n; i++) {
		s[i] = s[i - 1] + a[i];//每一个前缀和数组元素一定是它前一个前缀和数组元素加上自己的元素
	}

	for (int i = 1; i <= n; i++) {
		cout << s[i] << " ";
	}
	return 0;
}

谢谢大家的支持!

  • 45
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 42
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仍有未知等待探索

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值