题目描述

给定 n 个正整数组成的数列 a1,a2,,ana_1, a_2, \cdots ,a_n, 和 m 个区间 [li,ri][l_i,r_i],分别求这 m 个区间的区间和。对于所有测试数据,n,m105,ai104n,m\le10^5,a_i\le 10^4

输入格式

共 n+m+2 行。

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

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

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

第 4 到第 n+m+2 行,每行为两个正整数 li,ril_i,r_i ,满足1lirin1\le l_i\le r_i\le n

输出格式

共 m 行。

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

输入输出样例

输入 #1

4
4 3 2 1
2
1 4
2 3

输出 #1

10
5

说明/提示

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

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

对于100% 的数据:n,m105,ai104n,m\le 10^5,a_i\le 10^4

题目分析

题目需要我们求出m个区间的和,现在已知每次询问的区间边界lr。若采用暴力的方式,复杂度为O(nm)O(nm) 。此时,由于范围的问题会超时。

需要采用更快的方式进行处理。可以采用前缀和的思想,先提前进行预处理。

前缀和维护公式:sum[i]=sum[i1]+a[i]sum[i]=sum[i-1]+a[i]

求区间lrl\sim r 的总和公式:subSum=sum[r]sum[l1]subSum=sum[r]-sum[l-1]

区间总和复杂度为O(1)O(1),该代码的总的时间复杂度为O(n+m)O(n+m)

代码实现

#include <iostream>
#include <cstdio>
using namespace std;
const int N=1e5+5;
int a[N],sum[N];
int main(){
	int n,m,l,r;
	cin>>n;
	for(int i=1;i<=n;i++){//输入n个元素
		cin>>a[i];
		sum[i]=sum[i-1]+a[i];//维护前缀和,求出a[1]~a[i]的总和
	}
	cin>>m;
	while(m--){//重复m次
		cin>>l>>r;//输入询问的区间
		cout<<sum[r]-sum[l-1]<<endl;//求出a[l]~a[r]的总和
	}
	return 0;
}

Q.E.D.


( ノ^ω^)ノ゚ 稻 花 香 里 说 丰 年 , 听 取 WA 声 一 片 。(╥╯^╰╥)