那些年意外看到的方法

树状数组

学习来源1
学习来源2

关于树状数组,顾名思义,就是数形状的数组,主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值。
概述图如下(以数组C代指树状数组,以数组A代指原数组)

可看出:
C1=A1
C2=A1+A2
C3=A3
C4=A1+A2+A3+A4
C5=A5
C6=A5+A6
C7=A7
C8=A1+A2+A3+A4+A5+A6+A7+A8
……
一般规律:Cn=(An-2k+1)+…+An,其中,k取使得2k不大于An的最大值。
快速获取2k的方法如下:

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

树状数组的C++实现如下:

class treeArray {
private:
	vector<int> c;//树状数组
    vector<int> a;//原数组
public:
    void initi(int length) {//初始化树状数组,全部置零
        c.resize(length,0);
    }
    int lowBit(int x) {
        return x&(-x);
        //关于x&(-x)
        //假如x为奇数,那么x&(-x)=1
        //假如x为偶数,令x&(-x)=n,则x%n=0且n=2^m,m是可以取的最大值
    }
    void Update(int pos) {//更新树,pos位置数加1
        while(pos<c.size()) {
            c[pos]+=1;
            pos+=lowBit(pos);
        }
    }
    int query(int pos) {//求小于等于该位置的数的和
        int res=0;
        while(pos>0) {
            res+=c[pos];
            pos-=lowBit(pos);
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值