先累计再查一段
这一课只练一件事:用 把连续一段加起来。先填 sum[],再查任意 :sum[r] - sum[l - 1]。用 a = [2, 5, 1, 4] 走三步,再处理从第一个元素开始,并看 漏掉 a[l] 会怎样。多次查询时预处理大约是 ,每次查询一次减法。二维前缀和、差分数组、树状数组是拓展。这里不会在浏览器里运行 C++。
任务 1:先选出前缀和是什么、区间怎么查
不是把某一个格子单独存下来。它先填 ,再查连续一段的 。点不认识的词可看基础解释。
必会:能说出 sum[i] 的含义,并能写出区间公式。这里不会在浏览器里运行 C++,只练习选择和走过程。
sum[i] 表示什么?前缀和 · 必会
查询区间 [l, r] 的和该用哪条公式?区间和 · 必会
任务 2:按顺序给 [2, 5, 1, 4] 填前缀和
最小示例:下标从 1 开始,a[1]=2,a[2]=5,a[3]=1,a[4]=4,并且 sum[0] = 0。按顺序点三步,先写 sum[1] = 2,再写 sum[2] = 7,最后填完 sum[4] = 12。这里不会在浏览器里运行 C++。
必会:能解释每一格怎么累加。边界:从第一个元素开始也要填;不要跳过 sum[1] = 2 这一步。n 和 q 到 1e5 时,先花大约 n 次填表,再每次查询一次减法,比每次重新相加更能通过。
- int a[5] = {0, 2, 5, 1, 4}; // a[1..4]
- int sum[5] = {0}; // sum[0] = 0
- sum[i] = sum[i - 1] + a[i];
- // 查询 [l, r]:sum[r] - sum[l - 1]
填表走完了,现在亲手把填每一格的那一行敲出来: 的第 i 格要接住上一格的累计。下面是只读脚手架,只留一空给你敲键盘。
- int a[5] = {0, 2, 5, 1, 4}; // a[1..4]
- int sum[5] = {0}; // sum[0] = 0
- for (int i = 1; i <= 4; i++) {
- ; // 填这一格
- }
- // 查询 [l, r]:sum[r] - sum[l - 1]
sum[i] = sum[i - 1] + a[i]; // i = 3 时:上一格 7,加上 a[3] = 1,得到 8
任务 3:查一段,并看从第一个元素开始会怎样
建议掌握:查 [2, 4] 要用 sum[4] - sum[1]。从第一个元素开始时, 减的是 sum[0] = 0。写成 sum[r] - sum[l] 会漏掉 a[l]。
必会 / 建议掌握 / 拓展:必会是构造前缀和并用 sum[r] - sum[l - 1] 查询。建议掌握是处理 l=1,以及说明减错一格会漏掉左端点。二维前缀和、差分数组、树状数组是拓展,现在不用当硬门槛。
- // a = [2, 5, 1, 4],sum = [0, 2, 7, 8, 12]
- // [2, 4] = 5 + 1 + 4 = 10
- sum[4] - sum[1]; // 12 - 2 = 10
- // [1, 3] 从第一个开始:sum[3] - sum[0] = 8
先选出查询 [2, 4] 该怎么写:
再选出从第一个元素开始该怎么处理:
任务 4:随机小测,看看你是否真的懂了
每次从本课题库抽出三道不同的选择题。题目与解析已通过校验,答完后看解析,不要只看分数;拿不准就回到对应任务再看一遍。