树状数组(瞎bb) [树状数组]
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) [树状数组]的更多相关文章
- HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Tota ...
- 计蒜客 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 ...
- bzoj1901--树状数组套主席树
树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树
题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- BZOJ1901 - Dynamic Rankings(树状数组套主席树)
题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t 要求你把第i个数修改为t 题解 动态的区间第k ...
- bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1384 Solved: 629[Submit][Stat ...
- [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】
题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...
随机推荐
- JavaScript 扫描枪使用(一)
JavaScript 扫描枪应用(一)com.js为主要的代码实现,test.html文件为测试的页面,其中包括了com.js文件中方法的调用.以下为测试成功代码:com.js //com.js /* ...
- 用require.js封装原生js轮播图
index.html页面: <!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...
- H5JS二维动画制作!two.js的基本操作class1
今天介绍一个网络上并不常用的插件two.js,刚开始学习的过程中,发现网上并没有合适的教程,在此发表基本操作 two.js是一款网页二维绘图软件,可以在指定区域内产生自设的各种动画效果 下载网址如下: ...
- java编码详解
举个例子 我们在开发过程中,特别是多种编码格式并存的情况下,很容易遇到乱码问题. 假如有一个GBK编码java文件,然后再使用-Dfile.encoding=GBK参数,写入的文件中哪些是乱码呢.那如 ...
- Vuejs技术栈从CLI到打包上线实战全解析
前言 本文是自己vue项目实践中的一些总结,针对Vue2及相关技术栈,实践中版本为2.3.3. 开发前须知 vue-cli 在开发前,我们要至少通读一遍vue官方文档和API(看官方文档是最重要的,胜 ...
- oracle 树形表结构查询 排序
oracle 树形表结构排序 select * from Table start with parentid is null connect by prior id=parentid order SI ...
- 关于ZendStudio 10.5的破解 包括mac
一. 下载ZendStudio 10.5 首先下载ZendStudio 10.5 我使用的是mac版 下载地址是: http://downloads.zend.com/studio-eclipse/1 ...
- 【LeetCode】219. Contains Duplicate II
题目: Given an array of integers and an integer k, find out whether there are two distinct indices i a ...
- 13.如何生成订单号,用uuid
String orderNum = UUID.randomUUID().toString().replaceAll("-", "");
- PAT-1099(Build A Binary Search Tree)
题目见这里 分析:分四步进行 1)根据给定的结点情况建二叉树 2)对输入的键值排序(asending) 3)对二叉树中序遍历,同时对应赋key值 4)层次遍历(队列应用) 题目并不困难,但是我误入了 ...