动态连续和查询问题

问题描述

给定一个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;
}

 

posted @ 2019-07-24 18:36  寒方  阅读(223)  评论(0编辑  收藏  举报