P8218 求区间和【前缀和】

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

题目描述

给定 n n n 个正整数组成的数列 a 1 , a 2 , ⋯   , a n a_1, a_2, \cdots, a_n a1,a2,,an m m m 个区间 [ l i , r i ] [l_i,r_i] [li,ri],分别求这 m m m 个区间的区间和。

对于所有测试数据, n , m ≤ 1 0 5 , a i ≤ 1 0 4 n,m\le10^5,a_i\le 10^4 n,m105,ai104

输入格式

第一行,为一个正整数 n n n

第二行,为 n n n 个正整数 a 1 , a 2 , ⋯   , a n a_1,a_2, \cdots ,a_n a1,a2,,an

第三行,为一个正整数 m m m

接下来 m m m 行,每行为两个正整数 l i , r i l_i,r_i li,ri ,满足 1 ≤ l i ≤ r i ≤ n 1\le l_i\le r_i\le n 1lirin

输出格式

m m m 行。

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

输入输出样例 #1

输入 #1

4
4 3 2 1
2
1 4
2 3

输出 #1

10
5

说明/提示

样例解释:第 1 1 1 到第 4 4 4 个数加起来和为 10 10 10。第 2 2 2 个数到第 3 3 3 个数加起来和为 5 5 5

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

对于 100 % 100 \% 100% 的数据: 1 ≤ n , m ≤ 1 0 5 1 \le n, m\le 10^5 1n,m105 1 ≤ a i ≤ 1 0 4 1 \le a_i\le 10^4 1ai104

问题链接: P8218 求区间和
问题分析: 二分问题,不解释。
参考链接: (略)
题记: (略)

AC的C++语言程序如下:

/* P8218 求区间和 */

#include <iostream>

using namespace std;

const int N = 100000;
int a[N + 1], presum[N + 1]; 

int main() 
{
	int n, m;
	cin >> n;
	presum[0] = 0;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		presum[i] = presum[i - 1] + a[i];
	}
	cin >> m;
	for (int i = 1; i <= m; i++) {
		int l, r;
		cin >> l >> r;
		cout << presum[r] - presum[l - 1] << endl;
	}
	return 0;
}
### 关于洛谷 P8218 区间的算法实现 对于洛谷平台上的题目 **P8218 1.1 区间**,其核心思想在于利用前缀和来高效计算多个区间。以下是详细的分析与实现。 #### 前缀和的概念 前缀和是一种预处理技术,通过预先计算数组的部分,可以快速查询任意区间。定义 `s[i]` 表示从数组的第一个元素到第 `i` 个元素的累加,则有: \[ s[i] = a[1] + a[2] + \dots + a[i] \] 因此,任何区间 `[l, r]` 的可以通过简单的减法得到: \[ \text{sum}[l, r] = s[r] - s[l-1] \] 其中需要注意的是当 `l=1` 时,`s[l-1]` 应视为 `0`[^5]。 #### 实现步骤说明 为了完成该问题的需,我们需要执行以下操作: 1. 构建前缀和数组 `s[]`。 2. 对于每一个询问区间 `[l, r]`,按照上述公式计算并返回结果。 下面是基于 C++ 的具体代码实现: ```cpp #include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m; cin >> n; // 数组大小 vector<long long> a(n + 1, 0); // 初始数组,下标从1开始 for(int i = 1;i<=n;i++) cin>>a[i]; // 计算前缀和 vector<long long> s(n + 1, 0); for(int i = 1;i<=n;i++) s[i] = s[i-1] + a[i]; cin >> m; // 查询次数 while(m--){ int l, r; cin >> l >> r; cout << (s[r] - s[l-1]) << "\n"; // 输出区间 } return 0; } ``` 此程序首先读取输入数据构建原始数组 `a[]` 并计算对应的前缀和数组 `s[]`。随后接受多次查询请,并依据前述公式迅速给出答案[^1]。 #### 时间复杂度分析 - 构造前缀和的时间复杂度为 \(O(n)\),因为只需遍历一次原数组即可完成初始化。 - 每次查询的操作时间复杂度为 \(O(1)\),得益于前缀和技巧的应用使得无需重复扫描整个目标区间。 综上所述,整体解决方案具有较高的效率,非常适合解决此类涉及大量区间的问题场景。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值