树状数组原理及模板

原创 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);
} 


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

相关文章推荐

树状数组模板

树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元...

树状数组 模板

早就想着把以前搞acm的算法复习一遍,那可是瑰宝啊,一直没时间,之前面实习就有此感慨,以前学的算法都忘了,明日要去面个不知名的公司,准备下吧,先把树状数组和TRIE图复习下,明天凑合应对。 不多说,...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

hdu 1892(二维树状数组模板)

#include #include #include #include using namespace std; const int size = 1002; int C...

ACM 逆序对 hdu 4911 Inversion 离散化 树状数组模板

ACM 逆序对  设逆序对

树状数组求逆序数(模板)

树状数组求逆序数模板

树状数组、线段树模板(一)——单点更新 + HDU 1166 敌兵布阵

http://acm.hdu.edu.cn/showproblem.php?pid=1166 此题考查RSQ(Range Sum Query)。 模板如下: /*343ms,744KB*/ ...

树状数组模板区间更新 区间询问

14、树状数组 (1)、单点增减+区间求和 思路:C[x]表示该点的元素:sum(x)=C[1]+C[2]+……C[x] int arr[MAXN]; inline int sum(int x)...

模板,树状数组

树状数组的神奇在于省空间和时间; 空间复杂度O(

Mobile phones POJ1195(二维树状数组模板题)

Mobile phones Time Limit: 5000MS   Memory Limit: 65536KB   64bit IO Format: %lld & %llu...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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