【树状数组】

树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值。

                                                       ——百度百科

明确一个概念:

lowbit  取出二进制的最后一个1

x&(-x)

比如说:

6 0000110->0000010 (2)

3 0000011->0000001 (1) -


 

 

单点修改

根据这图

A[4]->C[4],C[8]

100->100, 1000

A[3]->C[3],C[4],C[8]

11->11,100,1000

所以 就是 每次加上lowbit

 

void Add_tarr(int pos,int delta)
{
    for (;pos<=n;)
    {
        tarr[pos]+=delta;
        pos+=pos&(-pos);
    }
}

 

根据这个 建立tarr数组

就是一边读,一边Add

    for (int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            Add_tarr(i,a[i]);
        }

所以这时候要注意: Add  中  pos <=n 中的 = 不要漏掉,因为 build过程最后一个元素  pos==n 

查询前缀和

 

还是上面那张图

7->c[7]+c[6]+c[4]

111->111+110+100

5->c[5]+c[4]

101->101+100

3->c[3]+c[2]

可以看出 这是pos一直减去lowbit,减到0。

int Qry_tarr(int pos)
{
    int sum=0;
    for (;pos;)
    {
        sum+=tarr[pos];
        pos-=pos&(-pos);
    }
    return sum;
}

所以 就可以用两个前缀和相减来查询区间和

 

 

敌兵布阵 代码

#include<iostream>
#include<cstdio>
#include<cstring> 
#define N 50010
using namespace std;
int tarr[N],a[N];
int n,T,x,y;
char s[10];
void Add_tarr(int pos,int delta)
{
    for (;pos<=n;)
    {
        tarr[pos]+=delta;
        pos+=pos&(-pos);
    }
}
int Qry_tarr(int pos)
{
    int sum=0;
    for (;pos;)
    {
        sum+=tarr[pos];
        pos-=pos&(-pos);
    }
    return sum;
}
int main()
{
    scanf("%d",&T);
    for (int I=1;I<=T;I++){    
        memset(a,0,sizeof(a));
        memset(tarr,0,sizeof(tarr));
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            Add_tarr(i,a[i]);
        };
        printf("Case %d:\n",I);
        for (;1;){
            cin>>s;
            if (s[0]!='E')scanf("%d%d",&x,&y);
            if (s[0]=='A') Add_tarr(x,y);
                else if (s[0]=='S') Add_tarr(x,-y);
                    else if (s[0]=='Q') printf("%d\n",Qry_tarr(y)-Qry_tarr(x-1));
                        else break;
        }
    }
}

 

posted @ 2016-04-28 19:41  mengyue  阅读(157)  评论(0编辑  收藏  举报