【P8218 求区间和】一维前缀和入门完整题解博客

一、题目题意

给定长度为 $n$ 的整数序列,再给出 $m$ 次区间询问,每次给出区间左右端点 $l,r$,输出区间 $[l,r]$ 内所有数字的总和。

样例解读

输入:

4
4 3 2 1
2
1 4
2 3

序列:$[4,3,2,1]$

  1. 区间 $[1,4]$:$4+3+2+1=10$
  2. 区间 $[2,3]$:$3+2=5$

输出两行依次为 $10、5$。

二、核心算法:一维前缀和

1. 前缀和定义

定义前缀和数组 $s$,其中 $s[i]$ 代表原数组前 $i$ 项的总和:

$$
s[i] = a_1 + a_2 + \dots + a_i
$$

递推公式:

$$
s[0]=0,\quad s[i] = s[i-1] + a[i]
$$

2. 区间和计算公式

对于任意区间 $[l,r]$,区间总和等于「前 $r$ 项和」减去「前 $l-1$ 项和」:

$$
sum(l,r) = s[r] - s[l-1]
$$

原理:$s[r]$ 包含 $1\sim r$ 全部数字,$s[l-1]$ 包含 $1\sim l-1$ 全部数字,两者相减恰好剩下 $l\sim r$ 的数字之和。
请添加图片描述

3. 算法优势

  1. 预处理仅需 $O(n)$ 时间
  2. 每次区间查询仅 $O(1)$ 常数时间
  3. 对比暴力每次循环累加 $O(n)$ 查询,海量询问下效率提升巨大。

三、完整AC代码

#include <bits/stdc++.h>
using namespace std;

int n, m;
int a[100005], s[100005];

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        s[i] = s[i - 1] + a[i];
    }
    scanf("%d", &m);
    for (int i = 1; i <= m; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        printf("%d\n", s[r] - s[l - 1]);
    }
    return 0;
}

四、分步解题流程

步骤1:输入序列长度 $n$,读入原数组 $a$

循环从 $i=1$ 到 $n$ 读取每个数字,同步计算前缀和数组 $s$:

  • $s[0]$ 程序默认初始为0;
  • 每一步 $s[i] = s[i-1] + a[i]$,完成预处理。

以样例数据演示前缀和数组生成:
$a[1]=4,\ a[2]=3,\ a[3]=2,\ a[4]=1$

$s[0]=0$

$s[1]=s[0]+4=4$

$s[2]=s[1]+3=7$

$s[3]=s[2]+2=9$

$s[4]=s[3]+1=10$

步骤2:输入询问次数 $m$

循环处理每一组询问,每次读入区间端点 $l、r$。

步骤3:套用公式计算区间和并输出

使用公式 $s[r]-s[l-1]$ 快速得到答案:

  1. 询问 $1\ 4$:$s[4]-s[0] = 10-0=10$
  2. 询问 $2\ 3$:$s[3]-s[1] = 9-4=5$

五、代码逐段讲解

  1. 数组定义

    int a[100005], s[100005];
    

    数组开到100005,适配题目数据范围;下标从1开始,规避边界 $l=1$ 时 $l-1=0$ 的特殊判断。

  2. 前缀和预处理循环

    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        s[i] = s[i - 1] + a[i];
    }
    

    边读入原数组,边递推计算前缀和,一次遍历完成预处理。

  3. 批量处理区间询问

    for (int i = 1; i <= m; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        printf("%d\n", s[r] - s[l - 1]);
    }
    

    每次查询直接通过前缀和差值算出区间和,无需再次遍历原数组。

六、题型总结

  1. 适用场景:静态数组(无单点修改)、大量区间求和查询;
  2. 模板记忆点:前缀和递推 $s[i]=s[i-1]+a[i]$,区间公式 $s[r]-s[l-1]$;
  3. 拓展延伸:二维前缀和、差分(支持区间修改+单点查询)是该知识点的延伸进阶内容。

posted on 2026-07-10 17:21  5iCode  阅读(13)  评论(0)    收藏  举报

导航