芜湖,家人们,先LOOK题
【模板】一维前缀和
题目描述
输入一个长度为n的整数序列。 接下来再输入m个询问,每个询问输入一对 l,r。 对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。
输入格式
第一行包含两个整数 n 和 m 。 第二行包含 n 个整数,表示整数数列。 接下来 m 行,每行包含两个整数 l 和 r ,表示一个询问的区间范围。
输出格式
共 m 行,每行输出一个询问的结果。
输入数据 1
5 3
2 1 3 6 4
1 2
1 3
2 4
输出数据 1
3
6
10
数据范围与约定
1≤l≤r≤n ,
1≤n,m≤100000,
−1000≤−1000≤数列中元素的值≤1000≤1000
欸嘿,家人们,简单不,我们只需要小小的暴力一下
#include<bits/stdc++.h>
using namespace std;
int a[100001],s[100001];
int main(){
int n,m;
cin>> n >> m;
for(int i = 1;i <= n;i++){
cin>> a[i];
}
while(m--){
int l,r,sum = 0;
cin>> l >> r;
for(int i = l;i <= r;i++){
sum += a[i];
}
cout<< sum << endl;
}
}
就可以成功的A……
啊,兄弟们,口误,TLE(超时)。
好好好,这么玩是吧,咋子A,
嗯……这得用上刚学的(也许吧)前缀和了
有人布吉岛前缀和是啥,往下看啊
我们先给出一序列数:
1 2 3 4 5 6 7 8 9 10
任务是求出一段子序列所有数加起来的和
有亿些小伙伴说,这不就直接一个循环就完了吗?
好的,这样做也行,但是!如果我把序列改成:
1 2 3 4……9999999 10000000
再把访问次数加多亿点,阁下又该如何应对?
那么,前缀和,启动!
看图
看得懂么,b就是我们前缀和的数组,b[i]存的值为a[1]到a[i]的值的和
b[i-1] 就是 a[1]到a[i-1]的值的和,那加上a[i]就得到b[i]了
呵呵,懂了咩?
又有人说,那如果他叫你求a[5]到a[10]的值咋办
嗯,简单
你不要a[1]到a[4]的值不就行了?(b[10]-b[4])
code:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int a[maxn],b[maxn];
int main(){
int n,m;
cin>> n >> m;//输入
for(int i = 1;i <= n;i++){
cin>> a[i];
}
for(int i = 1;i <= n;i++){
b[i] = b[i-1]+a[i];//求前缀和
}
while(m--){
int l,r;
cin>> l >> r;
cout<< b[r]-b[l-1] << endl;//输出
}
return 0;
}