Copyright:http://www.cnblogs.com/ZYBGMZL/

树状数组是一个利用一维数组和位运算组成的求解区间问题的高效数据结构,其构造如图所示

首先,我们要用它解决单点修改、区间查询的操作。

根据这张图我们建立一个数组bit[],下标就是图中显示的十进制数。bit[i]就表示了图中所示的一段区间的和,例如bit[6]=sum(5,6),bit[4]=sum(1,4)。

下标最大值为序列的长度n。

我们接下来要求一段序列中left到right的和,就可以转化为求sum(1,right)-sum(1,left)。

那么对于已知的x,怎么求sum(1,x)呢?

在这样一个栗子(上图)中,我们需要求得sum(1,6)的值,可以将其转化为求bit[6]+bit[4]。

显而易见,只要将6的二进制数0110的最低位1删去,就得到0100,对应了10进制的4。

再举一个栗子(如上图),我们想求sum(1,3)的值,只要求bit[2]+bit[3]就好了。

变化规律和上一个一样。(0011---->0010)

对于多段区间,也满足一样的规律(上图)。

我们总结,对于x,只要不断减去x中最低位的1,将得到的bit[x]相加就可以得到结果了。

用这样一个方法获取x的最低位1

x&-x

就得到了这样一个操作代码

 int sum(int x){
int sum=;
while(x){
x+=bit[x];
x-=x&-x;
}
return sum;
}

查询的问题解决了,接下来要处理修改的操作了。

举个栗子,假如对3点进行加a的操作,在bit[3]修改的同时,bit[4]和bit[8]也要相应修改。

观察这3个数(3,4,8)的二进制数,可以发现,只要不断地加上其最低位的1,就可以完成操作了。

0011+0001=0100

0100+0100=1000

再对所得的数判断是否大于n即可。

于是我们得到了这样一个单点修改的操作代码。

 void add(int x,int a){
while(x<=n){
bit[x]+=a;
x+=x&-x;
}
}

以上是树状数组操作最简单的模型,除此之外,树状数组还有区间修改、单点查询,以及区间修改、区间查询的功能。

区间修改、单点查询

 //改段求点型操作 

 //b[i]表示区间1...i一共变化的量
int b[];
//原始数组
int a[]; void ADD(int x, int c)
{
for (int i=x; i>; i-=i&(-i))
b[i] += c;
} void add(int left,int right,int c){
if(left-1) ADD(left-,-c);
ADD(right,c);
} int SUM(int x)
{
int s = ;
for (int i=x; i<=n; i+=i&(-i))
s += b[i];
return s+a[x];
}

区间修改、区间查询

 //改段求段型:
//这是最复杂的模型,需要两个辅助数组:B[i]表示a[1..i]到目前为止共被整体加了多少(和模型2中的一样)
//C[i]表示a[1..i]到目前为止共被整体加了多少的总和(或者说,C[i]=B[i]*i)。 //对于ADD(x, c),只要将B[x]加上c,同时C[x]加上c*x即可(根据C[x]和B[x]间的关系可得); //而ADD(x, c)操作是这样影响a[1..i]的和的:若x小于i,则会将a[1..i]的和加上x*c,
//否则(x>=i)会将a[1..i]的和加上i*c。也就是,a[1..i]之和 = B[i..N]之和 * i + C[1..i-1]之和。
//这样对于B和C两个数组而言就变成了“改点求段”(不过B是求后缀和而C是求前缀和)。
//另外,该模型中需要特别注意越界问题,即x=0时不能执行SUM_B操作和ADD_C操作。 //【1】修改操作:将A[l..r]之间的全部元素值加上c;
//ADD_B(r, c); ADD_C(r, c);
//if (l > 1) {ADD_B(l - 1, -c); ADD_C(l - 1, -c);}
//【2】求和操作:求此时A[l..r]的和。
//SUM(r) - SUM(l - 1)。 //B[i]表示区间1...i变化量
int B[];
//C[i]表示区间1...i变化量的总和,有c[i]=b[i]*i
int C[]; void ADD_B(int x, int c)
{
for (int i=x; i>; i-=i&(-i)) B[i] += c;
} void ADD_C(int x, int c)
{
for (int i=x; i<=n; i+=i&(-i)) C[i] += x * c;
} int SUM_B(int x)
{
int s = ;
for (int i=x; i<=n; i+=i&(-i)) s += B[i];
return s;
} int SUM_C(int x)
{
int s = ;
for (int i=x; i>; i-=i&(-i)) s += C[i];
return s;
} int SUM(int x)
{
if (x) return SUM_B(x) * x + SUM_C(x - ); else return ;
}

树状数组(瞎bb) [树状数组]的更多相关文章

  1. HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Tota ...

  2. 计蒜客 1460.Ryuji doesn't want to study-树状数组 or 线段树 (ACM-ICPC 2018 徐州赛区网络预赛 H)

    H.Ryuji doesn't want to study 27.34% 1000ms 262144K   Ryuji is not a good student, and he doesn't wa ...

  3. bzoj1901--树状数组套主席树

    树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...

  4. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  5. POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树

    题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...

  6. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  7. BZOJ1901 - Dynamic Rankings(树状数组套主席树)

    题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t  要求你把第i个数修改为t 题解 动态的区间第k ...

  8. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  9. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

随机推荐

  1. os模块学习小随笔

    os模块为python解释器与操作系统交互的接口 os.popen()   -------Open a pipe to or from command. The return value is an ...

  2. HTTP协议入门

    1.概述 (1)HTTP是应用层协议,是从Web服务器传输超文本到本地浏览器的传送协议,端口号为80.(2)默认情况下HTTP使用TCP,但是也可以基于以后存在的其他可靠传输协议.由于UDP无法提供可 ...

  3. 原生JS+Canvas实现五子棋游戏

    一.功能模块 先看下现在做完的效果: 线上体验:https://wj704.github.io/five_game.html 主要功能模块为: 1.人机对战功能 2.悔棋功能 3.撤销悔棋功能 二.代 ...

  4. jQuery未定义错误原因(jQuery is not define)

    使用jQuery时,必须把它写在最前面,这样浏览器才会先加载jQuery,否则会提示缺少对象. 正确 <script type="text/javascript" src=& ...

  5. CYQ.Data V5 分布式自动化缓存设计介绍(二)

    前言: 最近一段时间,开始了<IT连>创业,所以精力和写的文章多数是在分享创业的过程. 而关于本人三大框架CYQ.Data.Aries.Taurus.MVC的相关文章,基本都很少写了. 但 ...

  6. apache 基本vhost配置

    经常使用Apache虚拟主机进行开发和测试,但每次需要配置虚拟主机时都习惯性的ctrl+c和ctrl+v,这次由于重装系统,需要配置一个新的PHP开发环境虚拟主机,于是总结一下Apaceh配置http ...

  7. 去掉CI框架默认url中的index.php

    1:.htaccess //放置在根目录下,和入口文件index.php的同级目录<IfModule mod_rewrite.c>RewriteEngine onRewriteCond % ...

  8. TPYBoard自制微信远程智能温湿度计

    智能时代一夜间什么都能远程了.创业者想着如何做智能产品,如何做远程控制.DIY爱好者也想着如何自制各种奇妙的工具.这里和大家一起学习制作一款廉价的智能温湿度计.说它廉价是因为共计花费不过40元,说它智 ...

  9. PILLOW图片中加入中文 曲线救国Opencv

    索引 简述 准备 示例 效果图 结语 简述 我在使用opencv2或3的时候想要在图片上添加中文文字,需要去下载Freetype库,编译好链接到opencv库中才能中文的输出.网上大部分在图片中插入中 ...

  10. 常见的JQuery应用举例

    在学习JS之后,JQuery(以下简称JQ)为我们提供了一种更加便捷和简单的操作模式,利用它开发人员将更为高效的进行工作,下面将一些常见的问题进行举例. 1.点击某处弹出提醒,例如某些游戏在注册时会弹 ...