洛谷_3368 树状数组2

题意

如题,已知一个数列,你需要进行下面两种操作:
1.将某区间每一个数数加上x
2.求出某一个数的和

思路

用树状数组记录这个数列的差分数组,例如a[]={3,2,7,6,8}这个数列的差分数组为{3,-1,5,-1,2},我们可以从这个差分数组看出,第i个数的值就是差分数组的前i个的和。当我们进行修改,例如给2~4加上3,那么差分数组就会变成{3,2,5,-1,0},可以发现只是第2个和第5个变了,因为2~4中同时加上了2,所以它们的差分数组不会变,只会影响到它们两边的差分数组。修改的时候输出这个数的差分数列的前缀和就好了。

代码

#include<cstdio>
int n,m,tree[500001],z,x,y,last;
inline int lowbit(int x)
{
    return x&-x;
}
void insert(int p,int v)
{
    for (;p<=n;p+=lowbit(p))
        tree[p]+=v;
}
int find(int a)
{
    int o=0;
    for (;a;a-=lowbit(a)) o+=tree[a];
    return o;
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        insert(i,x-last);
        last=x;
    }
    for (int i=1;i<=m;i++)
    {
        scanf("%d",&z);
        if (z==1) 
        {
            scanf("%d%d%d",&x,&y,&z);
            insert(x,z);//左边的差分数组发生变化
            insert(y+1,-z);//右边的差分数组因为受到左边的影响所以加上-z
        }
        else 
        {
            scanf("%d",&x);
            printf("%d\n",find(x));//差分数组的前缀和就为这个数
        }
    }
}

猜你喜欢

转载自blog.csdn.net/SSL_hzb/article/details/80269925