知识点:前缀和
输入一个长度为 n 的整数序列,接下来再输入 m 个询问,1≤n,m≤100000。
每个询问输入一对 l,r,1≤l≤r≤n。
对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。
输入格式: 第一行包含两个整数 n 和 m。
第二行包含 n 个整数,表示整数数列,−1000≤数列中元素的值≤1000。
接下来 m 行,每行包含两个整数 l 和 r,表示一个询问的区间范围。
输出格式: 共 m 行,每行输出一个询问的结果。
输入样例: 1 2 3 4 5 5 3 2 1 3 6 4 1 2 1 3 2 4
输出样例:
思路 题目已经给了提示啦:前缀和
如果暴力计算,每次都遍历区间[l,r],复杂度最坏是O(mn)
使用前缀和数组pre,记录pre[i]记录前i个数的和,复杂度最坏是O(m)
知识点:一维数组前缀和
上次CSP的第二题,可以使用二维数组前缀和优化,才能满分。邻域均值
代码 如下是前缀和计算,最坏复杂度O(m)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> #include <vector> using namespace std ;int main () { int n, m; cin >> n >> m; vector <int > pre (n + 1 ) ; for (int i = 1 ; i <= n; i++) { int id; cin >> id; pre[i] = pre[i - 1 ] + id; } while (m--) { int a, b; cin >> a >> b; cout << pre[b] - pre[a - 1 ] << endl ; } return 0 ; }
如下是暴力计算,最坏复杂度O(mn),本题也不会超时(不太合理)。可对比下两种方法的耗时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream> #include <vector> using namespace std ;int main () { int n, m; cin >> n >> m; vector <int > ve; for (int i = 1 ; i <= n; i++) { int id; cin >> id; ve.push_back(id); } while (m--) { int a, b; cin >> a >> b; int sum = 0 ; while (a <= b) { sum += ve[a - 1 ]; a++; } cout << sum << endl ; } return 0 ; }