码迷,mamicode.com
首页 > 编程语言 > 详细

浅谈树状数组

时间:2018-10-28 22:10:39      阅读:299      评论:0      收藏:0      [点我收藏+]

标签:区间修改   进制   clu   简单   应该   pre   分享图片   img   index   

前言

首先来通过一道题目来展开说明

已知一个数列,你需要进行下面两种操作:

  1. 将某区间每一个数数加上x
  2. 求出某一个数的值
    数据规模:
    对于30%的数据:N<=8,M<=10
    对于70%的数据:N<=10000,M<=10000
    对于100%的数据:N<=500000,M<=500000

蒟蒻: 暴力修改
dalao: 线段树模板题

这可以用线段树去做,但是线段树的代码量太长了,很容易打错.其实这一题可以用树状数组做.

概念

树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询)。
这种数据结构(算法)并没有C++和Java的库支持,需要自己手动实现。在Competitive Programming的竞赛中被广泛的使用。树状数组和线段树很像,但能用树状数组解决的问题,基本上都能用线段树解决,而线段树能解决的树状数组不一定能解决。相比较而言,树状数组效率要高很多。

来自百度百科
其实树状数组的本质就是进行区间操作,求区间的和,并支持修改操作

算法讲解

树状数组从字面上来解释就是树状的数组

技术分享图片

这里的C数组就是树状数组,A数组是原数组
首先将C数组用A数组表示

C[1]=A[1];
C[2]=A[1]+A[2];
C[3]=A[3];
C[4]=A[1]+A[2]+A[3]+A[4];
C[5]=A[5];
C[6]=A[5]+A[6];
C[7]=A[7];
C[8]=A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8];

通过观察上面的式子我们可以发现一个规律:
C[i]=A[i-2^k+1]+A[i-2^k+2]+......A[i];(k为c数组下标的二进制中从最低位到高位连续零的长度)

但是这个东西我们怎么算呢?

这时候lowbit就很有用了
首先来看看lowbit的代码x&(-x)别看代码只有一行实际上是很有用的,他蕴含着许多深意放屁

实际上lowbit就是计算2^k次方的值
然后你知道这个就应该知道如何用树状数组了

code

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
using namespace std;
int a[500005*3+10],n,m;
int lowbit(int x) {
    return x&(-x);
}
inline void add(int x,int c) {
    while(x<=n) {
        a[x]+=c;
        x+=lowbit(x);
    }
}
inline int sum(int x) {
    int ans=0;
    while(x>0) {
        ans+=a[x];
        x-=lowbit(x);
    }
    return ans;
}
int main() {
    int L,x,y;
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) {
        scanf("%d",&x);
        add(i,x);
    }
    for(int ii=1; ii<=m; ii++) {
        scanf("%d%d%d",&L,&x,&y);
        if(L==1)
            add(x,y);
        else
            printf("%d\n",sum(y)-sum(x-1));
    }
    return 0;
}

浅谈树状数组

标签:区间修改   进制   clu   简单   应该   pre   分享图片   img   index   

原文地址:https://www.cnblogs.com/hbxblog/p/9866972.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!