[模版] BIT 树状数组

树状数组(BIT)

树状数组不仅仅只有求区间和的作用,还可以以此来查询区间最值或特殊值,(它的查询和插入操作都是O(logn)级别的);

它的最大好处就是简单易写,实现方便;

定义:

// * 数组大小
#define BITSZ (100)
// * 树状数组
int Bit[BITSZ]

单点添加函数:

void AddBit (int k,int val) {
    while (k<=BITSZ) {
        Bit[k]+=val;
        k+=k&-k;
    }
  return;
}

查询[1,k]的区间和函数:

int QueryBit (int k) {
    int sum=0;
    while (k>0) {
        sum+=Bit[k];
        k-=k&-k;
    }
  return sum;
}
时间: 2024-10-22 22:49:05

[模版] BIT 树状数组的相关文章

信奥一本通-树状数组模版题目-修改数列元素+求子数列元素和

给定n个数列,规定有两种操作,一是修改某个元素,二是求子数列[a,b]的连续和.数列的元素个数最多10万个,询问操作最多10万次. 输入 第一行2个整数n,m(n表示输入n个数,m表示有m个操作) 第二行输入n个数列. 接下来m行,每行有三个数k,a,b(k=0表示求子数列[a,b]的和:k=1表示第a个数加b). 输出 输出若干行数字,表示k=0时,对应的子数列[a,b]的连续和. 样例输入 10 5 1 2 3 4 5 6 7 8 9 10 1 1 5 0 1 3 0 4 8 1 7 5 0

深入理解树状数组

树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值:经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询). 百度上给出了令人难以理解的概念,其实这个东西我也是琢磨了一天,参考了大量博客的笔记才搞清楚了大致思路和原理,说说心得吧! 假设数组a[1..n],那么

HDU 1556 Color the ball 树状数组

Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10150    Accepted Submission(s): 5161 Problem Description N 个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从

杭电 HDU ACM 1166 敌兵布阵(树状数组)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 55172    Accepted Submission(s): 23126 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务

CodeForces 390E Inna and Large Sweet Matrix(树状数组改段求段)

树状数组只能实现线段树区间修改和区间查询的功能,可以代替不需要lazy tag的线段树,且代码量和常数较小 首先定义一个数组 int c[N]; 并清空 memset(c, 0, sizeof c); 1.单点修改 : c[x] += y; 对应的函数是 change(x, y); 2.求前缀和 :  对应的函数是 int sum(x) 两种操作的复杂度都是O(logn) 模板如下: int c[N], maxn; inline int Lowbit(int x){return x&(-x);}

树状数组的改段求段详解

以下是对于如何利用树状数组进行区间修改和区间查询的简介 可以代替不需要lazy tag的线段树,且代码量和常数较小 首先你需要学会树状数组,如果不会的话以下先讲解黑匣子使用树状数组的姿势 首先定义一个数组 int c[N]; 并清空 memset(c, 0, sizeof c); 1.单点修改 : c[x] += y; 对应的函数是 change(x, y); 2.求前缀和 :  对应的函数是 int sum(x) 两种操作的复杂度都是O(logn) 模版如下 int c[N], maxn; i

【BZOJ1901】Dynamic Rankings,树状数组套主席树

Time:2016.05.09 Author:xiaoyimi 转载注明出处谢谢 传送门(权限) 题面 1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6678 Solved: 2777 [Submit][Status][Discuss] Description 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a

BZOJ3262/洛谷P3810 陌上花开 CDQ分治 三维偏序 树状数组

原文链接http://www.cnblogs.com/zhouzhendong/p/8672131.html 题目传送门 - BZOJ3262 题目传送门 - 落谷P3810 题意 有$n$个元素,第$i$个元素有$a_i$.$b_i$.$c_i$三个属性,设$f(i)$表示满足$a_j\leq a_i$且$b_j\leq b_i$且$c_j\leq c_i$的$j$的数量.对于$d\in [0,n)$,求$f(i)=d$的数量. $n\leq 100000,max\{a_i,b_i,c_i|i

树状数组维护前缀和

树状数组是用来维护序列前缀和的数据结构.它的修改与求和都是O(logn)的,效率非常高. 我们设序列为A,则树状数组c中,c[i]记录序列A的区间[ i-lowbit(i)+1 , i ]中所有数的和. (树状数组是个好东西ovo)  树状数组在进行区间操作时,要从上到下访问,进行单点操作时,要从下到上访问.  树状数组维护序列前缀和的模版如下: #include <iostream> #include <cstdio> #define maxn 500005 using name