给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和。
例如,1 3 7 9 -1,查询第2个元素开始长度为3的子段和,1 {3 7 9} -1。3 + 7 + 9 = 19,输出19。
Input
第1行:一个数N,N为数组的长度(2 <= N <= 50000)。 第2 至 N + 1行:数组的N个元素。(-10^9 <= N[i] <= 10^9) 第N + 2行:1个数Q,Q为查询的数量。 第N + 3 至 N + Q + 2行:每行2个数,i,l(1 <= i <= N,i + l <= N)
Output
共Q行,对应Q次查询的计算结果。
前缀和
#include <bits/stdc++.h> using namespace std; const int maxn = 50010; typedef long long ll; int n,k; int s[maxn]; ll sum [maxn]; int main (){ scanf("%d ", &n); for(int i=1; i <= n; i++) scanf("%d",&s[i]); sum[0] = 0; for(int i=1;i <= n;i++){ sum [i] = sum[i-1] + s[i]; } scanf("%d", &k); for(int i=1;i <= k;i++){ int a,b; scanf("%d %d",&a,&b); printf("%lld ",sum[a+b-1] - sum[a-1]); } return 0; }
树状数组
#include <bits/stdc++.h> using namespace std; const int maxn = 50010; typedef long long ll; int n,k; ll bit[maxn]; void update(int i,int d){ while (i <= n){ bit[i] += d; i += i & (-i); } } ll sum (int i){ ll s = 0; while (i > 0){ s += bit[i]; i -= i & (-i); } return s; } int main (){ memset(bit,0,sizeof(bit)); scanf("%d", &n); int x; for(int i=1; i <= n; i++){ scanf("%d",&x); update(i,x); } scanf("%d", &k); for(int i=1;i <= k;i++){ int a,b; scanf("%d %d",&a,&b); printf("%lld ",sum(a+b-1) - sum(a-1)); } return 0; }