【洛谷 P8218】【深进1.例1】求区间和 题解(前缀和)

242 阅读2分钟

【深进1.例1】求区间和

题目描述

给定 nn 个正整数组成的数列 a1,a2,,ana_1, a_2, \cdots, a_nmm 个区间 [li,ri][l_i,r_i],分别求这 mm 个区间的区间和。

对于所有测试数据,n,m105,ai104n,m\le10^5,a_i\le 10^4

输入格式

第一行,为一个正整数 nn

第二行,为 nn 个正整数 a1,a2,,ana_1,a_2, \cdots ,a_n

第三行,为一个正整数 mm

接下来 mm 行,每行为两个正整数 li,ril_i,r_i ,满足1lirin1\le l_i\le r_i\le n

输出格式

mm 行。

ii 行为第 ii 组答案的询问。

样例 #1

样例输入 #1

4
4 3 2 1
2
1 4
2 3

样例输出 #1

10
5

提示

样例解释:第 11 到第 44 个数加起来和为 1010。第 22 个数到第 33 个数加起来和为 55

对于 50%50 \% 的数据:n,m1000n,m\le 1000

对于 100%100 \% 的数据:1n,m1051 \le n, m\le 10^51ai1041 \le a_i\le 10^4


思路

前缀和是一种处理数组区间问题的常用方法,它可以在预处理阶段用O(n)O(n)的时间复杂度求出所有前缀和,然后在每次查询阶段用O(1)O(1)的时间复杂度求出任意一个区间的和。

首先,程序定义了两个长度为NN的数组aass,分别用来存储输入的序列和序列的前缀和。然后,程序读入一个整数nn,表示序列的长度。

接着,程序进入一个循环,读入序列的每一个元素,并且在读入的同时,更新前缀和数组ss。这里,s[i]s[i]的值等于a[i]a[i]的值加上s[i1]s[i-1]的值,也就是说,s[i]s[i]的值是序列的前ii个元素的和。

然后,程序读入一个整数mm,表示将要进行的查询的数量。之后,程序进入一个循环,对每一个查询进行处理。每一个查询包含两个整数llrr,表示要查询的区间的起点和终点。程序通过输出s[r]s[l1]s[r] - s[l - 1]的值来得到查询的答案,这是因为s[r]s[r]的值是序列的前rr个元素的和,s[l1]s[l - 1]的值是序列的前l1l-1个元素的和,所以他们的差就是序列的第ll个元素到第rr个元素的和。


AC代码

#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;

const int N = 1e7 + 7;

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

int main() {
	s[0] = 0;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		s[i] = a[i] + s[i - 1];
	}
	cin >> m;
	for (int i = 1; i <= m; i++) {
		int l, r;
		cin >> l >> r;
		cout << s[r] - s[l - 1] << endl;
	}
	return 0;
}