树状数组原理及模板

原创 2016年08月30日 21:47:22


树状数组:

一. 作用:

1. 处理单点修改以及前缀查询

2. 特殊情况的区间修改与区间查询

二. 复杂度

修改: O(logn)

查询: O(logn)

空间: O(n)

三. 具体实现

生成

C[i]=Σa[j] (i-2^k

int lowbit(int x) {return x&-x;}
int work(int x) {int sum=0; for (;x;x-=lowbit(x)) sum+=C[x]; return sum;}
int Query(int l,int r) {return sum(r)-sum(l-1);}
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];

当ai增加x时如何修改C

(1) 令C[i]+=x。
(2) i+=lowbit(i)。
(3) 若i>n,退出,否则执行(1)。

void change(int i,int x){
    for (; i<=n; i+=lowbit(i)) C[i]+=x;
} 

区间增加,单点查询

令b[i]=a[i]-a[i-1]。
a[x]=∑b[j] (j<=x)
修改复杂度:O(1),查询复杂度(对b维护一个前缀和):O(1)


区间增加,区间查询和

b数组相关与上题相同
ans=(Σb[i])(i<=l)(r-l+1)-Σ(b[i]*i)(l

int a[10010];//数据 
int b[10010];//a[i]-a[i-1] 
int c[10010];//树状数组核心 

int lowbit(int x) {
    return x&-x;
}

void update(int x) {//更新单个c[x]
    c[x]=0; 
    for(int j=x-lowbit(x);j<=x;j++){
        c[x]+=a[j];
    }
}
void change(int i,int x) {//将a[i]的值增加x,并修改所有相关的c的值 
//  a[i]+=x;
    for(;i<=n;i+=lowbit(i))//n为数据的个数(a的长度) 
        c[i]+=x;
}

//单点修改,区间查询和 (35~43)
int preSum(int x) {//求前缀和 
    int sum=0;
    for(;x;x-=lowbit(x))
        sum+=c[x];
    return sum;
}
int query(int l,int r){
    return preSum(r)-preSum(l-1);
}

//区间增加,单点查询 (46~62)
int preB[10010];
void init() {
    preB[0]=0;
    for(int i=1;i<=n;i++){
        b[i]=a[i]-a[i-1];
        preB[i]=preB[i-1]+b[i];
    }
}
void modify(int l,int r,int v) {//[l,r]+v 
    b[l]+=v;
    b[r+1]-=v;
    for(int i=l;i<r+1;i++)
        preB[i]+=v;
}
int query(int x) {///查询a[x] 
    return preB[x];
}

//区间增加,区间查询和 (65~87)
int preB[10010];
void init() {
    preB[0]=0;
    for(int i=1;i<=n;i++){
        b[i]=a[i]-a[i-1];
        preB[i]=preB[i-1]+b[i];
    }
}
void modify(int l,int r,int v) {//[l,r]+v 
    b[l]+=v;
    b[r+1]-=v;
    for(int i=l;i<r+1;i++)
        preB[i]+=v;
}
int bii(int l,int r){
    int ans=0;
    for(int i=l;i<r+1;i++)
        ans+=b[i]*i;
    return ans;
}
int query(int l,int r) {
    return preB[l]*(r-l+1) - bii(l+1,r) + (preB[r+1]-preB[l]) * (r+1);
} 


版权声明:本文为博主原创文章,未经博主允许不得转载。

C++ 编译器处理模板的原理

编译器遇到模板方法定义时,会进行语法检查,但是并不编译模板。编译器无法编译模板定义,因为它不知道使用什么类型。不知道x和y的类型,编译器就无法为x=y这样的语句生成代码。 编译器遇到一个实例化的模板时...
  • u011206291
  • u011206291
  • 2016年10月26日 10:19
  • 1173

容斥原理【模板】

容斥原理:在计数时,必须注意无一重复,无一遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计...
  • u011676797
  • u011676797
  • 2015年05月07日 19:49
  • 1199

ThinkPHP的PHP变量传递到模板原理浅析

程序员就应该是站在前人的肩膀上前进,所以,分析优秀的开源产品以及框架我觉得是程序员必做事情。 最近在尝试自己独立编写一个程序,在后台用到了php模板,简单来说,就是模板中用原生态的PHP代码做循环、...
  • longxuu
  • longxuu
  • 2013年02月28日 14:38
  • 6270

模板匹配原理-1

原文:http://blog.csdn.net/liminlu0314/article/details/6194516  在遥感图像的几何纠正过程中,可能会用到控制点库的点片自动匹配。关于控制点片匹...
  • xuejiren
  • xuejiren
  • 2014年06月25日 08:47
  • 9928

Smarty模板执行原理

为了实现程序的业务逻辑和内容表现页面的分离从而提高开发速度,php 引入了模板引擎的概念,php 模板引擎里面最流行的可以说是smarty了,smarty因其功能强大而且速度快而被广大php web开...
  • u013474436
  • u013474436
  • 2015年11月24日 12:23
  • 1196

c++编译器模板机制剖析

编译器编译原理   gcc 基本概念 什么是 gcc,gcc(Gun Compiler Collection 缩写),最初是是作为 c 语言的编译器(Gun C Co...
  • liulongling
  • liulongling
  • 2016年03月23日 18:48
  • 877

模板引擎原理

模板编译用的还是比较多的,像template 、underscore的插件等等,不过随着vue ,angular ,avalon 等双向数据绑定的出现,也基本上用的不多了。都知道模板引擎都是正则匹配,...
  • u010427666
  • u010427666
  • 2017年02月03日 22:44
  • 206

基于边界的模板匹配的原理及算法实现

转载自http://blog.csdn.net/huixingshao/article/details/45560643 最近被Halcon中的基于边缘的模板匹配算法吸引到了,故找到...
  • lcydhr
  • lcydhr
  • 2016年06月05日 22:27
  • 657

前端模板的原理与实现

原文链接:https://segmentfault.com/a/1190000006990480 时下流行什么react, avalon, angular, vue什么,其核心都离不开前端模板。...
  • u013063153
  • u013063153
  • 2016年10月11日 12:56
  • 1619

JavaScript模板引擎的应用场景及实现原理

一、应用场景 以下应用场景可以使用模板引擎: 1、如果你有动态ajax请求数据并需要封装成视图展现给用户,想要提高自己的工作效率。 2、如果你是拼串族或者数组push族,迫切的希望改变现有的...
  • u013510614
  • u013510614
  • 2016年07月17日 08:44
  • 1127
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:树状数组原理及模板
举报原因:
原因补充:

(最多只允许输入30个字)