题目是这样的:
Sample Input
5
1 3 5 4 2
2
1 3
2 5
Sample Output
51
这道题如果不考虑时间的话很容易解,但最后会超时。
所以这道题的关键就在于如何用一层循环解决。
解决思路如下:
首先这道题在草稿纸上演算,拿输入样例来说,如果要知道某个区间打水的人花费的时间总和,可以先不看特定区间,先算出每个人打水需要的时间,我们把每个人打水需要的时间存到一个新的数组里,命名为b[n]
也就是
a[n] 1 3 5 4 2
b[n] 1 4 9 13 15
于是每个人打水需要的时间就有啦,他问时间和,假如说我们要的区间就是从第1个人到第n个人,也就是每次都是从第一个人开始的,如果是这种情况,我们则需要b1+b2+…+bn
如果两次循环不超时那分析到这里就已经没问题了,关键是如何不用双重循环来实现一个区间的加和呢。我们只能用一重循环的话,本来自闭了很久觉得impossible,但想了想没有什么是再加一个数组或者结合数学列个式子不能解决的了(误
于是我们还按照那个从1到n取区间走起,我们目的是求和b1+b2+…+bn ,那我们再来加个数组 c[n] c[i]是b[1]到b[i] 的加和
于是乎是酱紫
a[n] 1 3 5 4 2
b[n] 1 4 9 13 15
c[n] 1 5 14 28 43
也就是前缀和的前缀和
嗯…这个出来了,之后就是想如何实现任意区间,那不就用第三个数组做个减法的事嘛,其实题目中已经给提示了,取一个连续区间。因为用一重循环所以必须做到给出l,r就能算出结果,那就必须要写一个式子! 所以草稿纸上演算一下,不难得出
sum += (c[r]-c[l-1]-b[l-1]*(r-l+1))%1000000007;
于是肯定会想为啥要再取余一下(在这里没考虑过,于是卡了一个小时)因为本来就是long long int,进行加法会爆掉的的的 所以记得在这里取余一下
好啦,上代码(注意long longi nt
#include<stdio.h>
long long int n,q,l,r,i,j;
long long int sum=0;
long long int a[100100]={0};
long long int b[100100]={0};
long long int c[100100]={0};
int main(){
b[0]=0;
c[0]=0;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=b[i-1]+a[i];
c[i]=c[i-1]+b[i];
}
scanf("%d",&q);
for(j=1;j<=q;j++){
scanf("%d%d",&l,&r);
sum += (c[r]-c[l-1]-b[l-1]*(r-l+1))%1000000007;
}
printf("%d",sum%1000000007);
return 0;
}