树状数组学习笔记

树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询)。
这种数据结构(算法)并没有C++和Java的库支持,需要自己手动实现。在Competitive Programming的竞赛中被广泛的使用。树状数组和线段树很像,但能用树状数组解决的问题,基本上都能用线段树解决,而线段树能解决的树状数组不一定能解决。相比较而言,树状数组效率要高很多。
 
以上内容摘自百度。
 
树状数组是一种可以求前缀和的数据结构,寒假学习之后,做了几个题,借本文来总结一下,树状数组的知识。
 
lowbit函数背就可以了。
 
luogu树状数组1模板
 
#include<iostream>
#include<cstdio>
using namespace std;
int tree[500001],haha[500001],f1,f2,n,m,num;
int lowbit(int x)
{
    return x & -x;
}
void add(int x,int k)
{
    while(k<=n)
    {
        tree[k]+=x;
        k+=lowbit(k);
    }
    return ;
}
int sum(int x)
{
    int ans=0;
    while(x!=0)
    {
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&f1);
        add(f1,i);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&f1);
        if(f1==1)
        {
            scanf("%d%d",&f1,&f2);
            add(f2,f1);
            continue;
        }
        else
        {
            scanf("%d%d",&f1,&f2);
            num++;
            haha[num]=sum(f2)-sum(f1-1);
        }
    }
    for(int i=1;i<=num;i++)
    printf("%d\n",haha[i]);
    return 0;
} 

 

luogu 树状数组2 代码

 

#include<iostream>
#include<cstdio>
using namespace std;
int tree[500001],haha[500001],f1,f2,f3,n,m,num;
int a[500001];
int lowbit(int x)
{
    return x & -x; 
}
void add(int x,int k)
{
    while(k<=n)
    {
        tree[k]+=x;
        k+=lowbit(k);
    }
    return ;
}
int sum(int x)
{
    int ans=0;
    while(x!=0)
    {
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        add(a[i]-a[i-1],i);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&f1);
        if(f1==1)
        {
            scanf("%d%d%d",&f1,&f2,&f3);
            add(f3,f1);
            add(-f3,f2+1);
        }
        else
        {
            scanf("%d",&f1);
            num++;
            haha[num]=sum(f1);
        }
    }
    for(int i=1;i<=num;i++)
    printf("%d\n",haha[i]);
    return 0;
}

 

 
 
posted @ 2018-03-03 22:49  蒟蒻炖辣鸡  阅读(192)  评论(0编辑  收藏  举报