专栏文章

浅谈前缀和(一维)

算法·理论参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miod753x
此快照首次捕获于
2025/12/02 17:17
3 个月前
此快照最后确认于
2025/12/02 17:17
3 个月前
查看原文

前缀和的用途

前缀和是一种常用的算法技巧,通过预处理数组来快速计算某个区间的和。它的核心思想是利用空间换时间,预先计算出数组的前缀和,从而在查询时能够快速得到结果

一维前缀和的基本思想

一维前缀和的基本思想是构建一个新的数组 bb ,其中 bib_i 表示原数组从第 11 个元素到第 ii 个元素的和。这样,在查询某个区间 [l,r][l, r] 的和时,时间复杂度为 O(1)O(1)

求前缀和数组

前缀和数组的第 ii 项就是原数组从第 11 个元素到第 ii 个元素的和,用代码写出来很简单
CPP
for (int i = 1; i <= n; i++){
   b[i] = b[i - 1] + a[i];
}
bi1b_{i-1} 是前 i1i-1 项的和,那么求前 ii 项的和就用当前项 aia_i 加上 bi1b_{i-1} 就可以了
eg:eg:
原数组 ai=(0,1,2,3,4,5,6,7,8,9){a_i}=(0,1,2,3,4,5,6,7,8,9)
前缀和数组 bi=(0,1,3,6,10,15,21,28,36,45){b_i}=(0,1,3,6,10,15,21,28,36,45)

前缀和求区间和的公式

求出了前缀和数组又怎样求一个区间的和呢?
我们假设这个区间是 [l,r][l, r],原数组 a=(1,2,3,4,5)a=(1,2,3,4,5) ,那么前缀和数组 b=(1,3,6,10,15)b=(1,3,6,10,15) ,设 l=3l=3r=5r=5 ,显而易见,区间和为 1212 ,那怎么用代码写出来呢?我们可以用前 55 项的和减去前 22 项的和得到区间和,这与 llrr 有什么关系呢?我们发现 rr 就等于 55l1l-1 就等于 22 ,所以我们得出一个公式:
[l,r][l,r] 的区间和 =brbl1=b_r-b_{l-1}
所以用代码写就是
CPP
int ans = b[r] - b[l - 1];//[l,r] 的区间和

一维前缀和最终代码

CPP
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, a[N], b[N], l, r;

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
		b[i] = b[i - 1] + a[i];//求前缀和数组
	}
	scanf("%d%d", &l, &r);
	int ans = b[r] - b[l - 1];//[l,r] 的区间和
	printf("%d", ans);
	
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...