问题描述
给定一个n个元素的数组a1,a2,a3…..an,你的任务是设计一个数据结构支持以下两种操作:
(1)Add(x,d): 让a[x]增加d
(2)Query(L,R): 计算L到R的区间和
输入文件
输入的第 1 行包含一个整数 n 表示序列长度。
接下来一行包含n个整数,分别是A[1], A[2], ..., A[n]。
接下来一行包含一个整数m,表示询问个数。
接下来每行一个询问:
0 x y : 将 A[x]增加y
1 x y : 询问x到y的区间和
输出文件
对于每个询问1 x y,输出一行为要求的答案。
输出样例
4
1 2 3 4
4
1 1 3
0 3 -3
1 2 4
1 3 3
输出样例
6
6
0
限制与约定
保证所有A[i]的绝对值在任何时刻不超过10000
对于20%的数据, 1<=m <=1000,1<=n <=1000
对于另外30%的数据,保证没有修改只有询问
对于100%的数据 1<=n<=50000 , 1<=m<=100000
时间限制:1s
空间限制:128MB
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int maxn = 100000 + 1; int lowbit[maxn],n,a[maxn],f[maxn],m; void modify(int pos,int dx) { for(int i=pos;i<=n;i+=lowbit[i]) f[i]+=dx; return ; } int query(int pos) { int sum(0); for(int i=pos;i;i-=lowbit[i]) sum+=f[i]; return sum; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) lowbit[i]= (i&-i); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); modify(i,a[i]); } scanf("%d",&m); while(m--) { int q,x,y; scanf("%d%d%d",&q,&x,&y); if(q==0) modify(x,y); else if(q==1) printf("%d\n",query(y)-query(x-1)); } return 0; }