前缀和【C语言】

简介: 前缀和算法是一种优化技巧,常用于解决数组问题中的查询操作,例如区间求和、区间最大值/最小值等。其基本思路是先预处理出一个前缀和数组,在需要查询时通过计算前缀和数组的差值来得到查询结果。这个算法可以在O(1)的时间内回答很多查询问题,因此在实际编程中被广泛使用。

前缀和介绍


前缀和算法是一种优化技巧,常用于解决数组问题中的查询操作,例如区间求和、区间最大值/最小值等。其基本思路是先预处理出一个前缀和数组,在需要查询时通过计算前缀和数组的差值来得到查询结果。这个算法可以在O(1)的时间内回答很多查询问题,因此在实际编程中被广泛使用。1e2e00b6ccba6a24ccd0d2704e53c6f.png

起源


前缀和算法的起源可以追溯到卡特兰数学家 Eugène Charles Catalan 在 1878 年提出的连续子序列问题。该问题要求在一个长度为 n 的数组中,找出所有连续子序列的和,并统计其中等于某个给定值的子序列的数量。Catalan 发现,如果先计算出数组的前缀和,则任意两个位置之间的子序列和可以通过前缀和数组的差值计算得出。通过这个思路,他成功地解决了这个问题,并将前缀和算法推广到更广泛的应用领域。

用法


前缀和算法是一种常用于数组问题的优化技巧,可以在O(1)的时间内回答很多查询问题,例如区间求和、区间最大值/最小值等。


C语言前缀和算法的基本思路是:先预处理出一个前缀和数组 prefix_sum,其中 prefix_sum[i] 表示原始数组 nums 的前 i 个元素的和;然后在需要查询时,通过计算 prefix_sum 的差值来得到查询结果。08b2bff1ab348d82f17fa4daaea8487.png

代码


#include <stdio.h>
const int MAXN = 100005;
int nums[MAXN], prefix_sum[MAXN];
int main() {
    int n;
    scanf("%d", &n);
    // 输入原始数组
    for (int i = 1; i <= n; i++) {
        scanf("%d", &nums[i]);
    }
    // 预处理前缀和数组
    for (int i = 1; i <= n; i++) {
        prefix_sum[i] = prefix_sum[i-1] + nums[i];
    }
    // 查询区间 [l, r] 的和
    int l, r;
    scanf("%d %d", &l, &r);
    printf("区间 [%d, %d] 的和为:%d\n", l, r, prefix_sum[r] - prefix_sum[l-1]);
    return 0;
}

解析


上述代码中,我们首先定义了一个长度为 MAXN 的整型数组 nums 和 prefix_sum,其中 nums 存储原始数组,prefix_sum 存储前缀和数组。在主函数中,我们先读入原始数组 nums,并且计算出前缀和数组 prefix_sum。这里需要注意的是,为了方便计算,我们将 prefix_sum[0] 初始化为 0,这样求解 prefix_sum[i] 就不需要判断 i 是否等于 0。


在查询区间 [l, r] 的和时,我们可以直接用 prefix_sum[r] - prefix_sum[l-1] 计算出答案。这个式子的意思是,区间 [l, r] 的和等于前 r 个元素的和 prefix_sum[r] 减去前 l-1个元素的和 prefix_sum[l-1]。由于 prefix_sum[0] 已经预处理为 0,所以我们可以使用 prefix_sum[l-1] 而不必担心越界问题。


除了求和之外,前缀和算法还可以用来回答很多其他类型的查询问题,例如查询区间最大值/最小值、统计区间内元素个数等。通过巧妙地设计前缀和数组,我们可以在O(n)的时间内预处理出所有需要查询的结果,在O(1)的时间内回答每次查询,从而大大提高程序的效率。eabebb75706c0a86d272b00f6d7f8dd.png

目录
相关文章
|
1月前
|
C语言
C语言--杨氏矩阵
C语言--杨氏矩阵
14 0
|
12月前
|
存储 编译器 Linux
C语言例题讲解(中)
C语言例题讲解(中)
|
机器学习/深度学习 C语言
(C语言)全排列问题
(C语言)全排列问题
95 0
|
C语言
C语言例题20:
 题目要求:输入3个数,按由大到小的顺序输出   #include void main() { //第一种方法:推理法 int a,b,c; scanf("%d%d%d",&a,&b,&c); if(a>=b) ...
704 0
|
C语言
C语言例题22:
题目要求:用指针方式实现strlen函数的功能   #include int mystrlen(char * p); void main() { char ch[10]; printf("输入字符串的内容/n"); ...
659 0
|
C语言
C语言例题25:
 题目要求:一维数组实现杨辉三角   #include void main() { int i,j,x; //x,y是二个计数器,X是欲显示的行数 scanf("%d",&x); int a[20]={1...
801 0
|
C语言
C语言例题19:
题目要求:编写一个函数,打印学生成绩,该数组中有3个学生的数据记录,每个记录包括num,name,score[3],用主函数输入这些记录,输入学号,将该学号的学生记录输出   #include struct studen...
736 0
|
C语言 Serverless
C语言例题18:
题目要求:       要求1:定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天?注意闰年问题      要求2:写一个函数days,实现其功能。
713 0
|
C语言 机器学习/深度学习
C语言例题23:
题目要求:输入两个数,求其最大公约和最小公倍数   #include void main() { int m,n,x,y; printf("输入两个正整数/n"); scanf("%d%d",&m,&n); if...
789 0
|
C语言 人工智能
C语言例题8:
 题目要求:求出所有的4位数,符合abcd=(ab+cd)2次方 #include void main() { int i; int a; for(i=1000;i
605 0

热门文章

最新文章