Fenwick tree (1) - in order to prepare the future with

To study Fenwick tree system, it is recommended to learn about " binary decomposition ," " doubling concept". 

Brief introduction

Fenwick tree is a way inO(logn)In the complete range[1,n]The additive interrogation (sum, product), inO(logn)The complete single modified data structure data (two or more kinds of basic operation). 
Its small code amount, small constant, but most do not support the request value interval (can use the segment tree ).

principle

In fact, the core idea Fenwick tree is doubled , fundamentally, Fenwick tree is the enhanced version of the ST algorithm. 

ST Table problem of non-added main processing section, and similar thereto Fenwick tree can be determined interval may increase the problem.



template:

int lowbit(int x){
    return x&(-x);
}
int que_sum(int x){
    int sum = 0;
    for( ; x > 0; x -= lowbit(x)) 
        sum += val[x];
    return sum;
}
void update(int x, int k){
    for( ; x <= n; x += lowbit(x)) 
        val[x] += k;
}


Interval operation may use a differential , for a range[l,r]We first processing window[1,l1]In processing window[1,r]And then do the subtraction, you can get the answer. 
For the modification of the operation, each modification of a point, as long as we have updated coverage information section of this point just fine, the next piece of information to find a method of digital x coverage isx+=lowbit(x), So that current can carry the least significant bit, the number of points which must be covered with a minimum of modification, this has been added to the stop is greater than n. 
This optimization is an array of simple multiplication tree most fundamental optimization, because the only line of binary decomposition, so reducing maintenance information, the information maintenance support changes, constant change is very small. 







Preparatory function [ edit ]

Lowbit define a function that returns the parameters into binary values ​​represented by the position of the last one.

For example, Lowbit (34) of the return value will be 2; and Lowbit (12) returns 4; Lowbit (8) 8 returns.

The 34 into binary, is 0010 0010, the "last 1" refers to the {\ displaystyle 2 ^ {0}2^{0} } bits forward numbers, see the first one, i.e. {\ displaystyle 2 ^ {1}}2^{1} 1 -position.

On the program, ((Not I) +1) And I show the last value of a 1,

Example 34 still, Not result is 1101 1101 0010 0010 (221), after adding a 1101 1110 (222), and the 00,100,010 11,011,110 as AND, to give 0000 0010 (2).

Lowbit of a simple method for finding: (C ++)

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


Reference + Recommended:

http://blog.csdn.net/yhf_2015/article/details/53844284

http://blog.csdn.net/int64ago/article/details/7429868

http://blog.csdn.net/x_iya/article/details/8943264


Wikipedia saying:

Fenwick tree [ edit ]

Encyclopedia Wikipedia, the free
The array [1, 2, 3, 4, 5] to create an array corresponding to the tree

Fenwick tree or a binary index tree ( English: Binary Indexed Tree ), and its inventor named Fenwick tree, first proposed by Peter M. Fenwick in 1994 with the Data Structure for New Cumulative A Frequency the Tables [1] published in the title PRACTICE AND EXPERIENCE in SOFTWARE. Its intention is to solve the compressed data in the cumulative frequency (Cumulative Frequency) computational problems, now used for efficient computation of the prefix and the number of columns, and the interval. It may be {\ displaystyle O (\ log nO(\log n) )} to give any prefix and time {\ DisplayStyle \ SUM _ {I =. 1} ^ {J} A [I],. 1 <= J <= N}{\displaystyle \sum _{i=1}^{j}a[i],1<=j<=N} , and at the same time support {\ displaystyle O (\ log nO(\log n) )} modification support dynamic single time point values. Space complexity {\ DisplayStyle O (n-)}O (n) .


Preparatory function [ edit ]

Lowbit define a function that returns the parameters into binary values ​​represented by the position of the last one.

For example, Lowbit (34) of the return value will be 2; and Lowbit (12) returns 4; Lowbit (8) 8 returns.

将34转为二进制,为0010 0010,这里的"最后一个1"指的是从{\displaystyle 2^{0}}2^{0}位往前数,见到的第一个1,也就是{\displaystyle 2^{1}}2^{1}位上的1.

程序上,((Not I)+1) And I表明了最后一位1的值,

仍然以34为例,Not 0010 0010的结果是 1101 1101(221),加一后为 1101 1110(222), 把 0010 0010与1101 1110作AND,得0000 0010(2).

Lowbit的一个简便求法:(C++)

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

新建[编辑]

定义一个数组 BIT,用以维护{\displaystyle A}A的前缀和,则:

{\displaystyle BIT_{i}=\sum _{j=i-lowbit(i)+1}^{i}A_{j}}{\displaystyle BIT_{i}=\sum _{j=i-lowbit(i)+1}^{i}A_{j}}

具体能用以下方式实现:(C++)

void build()
{ 
    for (int i=1;i<=MAX_N;i++)
    {
        BIT[i]=A[i];
        for (int j=i-1; j>i-lowbit(i); j--)
            BIT[i]+=A[j];
    }
}
//注:这里的求和将汇集到非终端结点(D00形式)
//BIT中仅非终端结点i值是 第0~i元素的和
//终端结点位置的元素和,将在求和函数中求得

修改[编辑]

假设现在要将{\displaystyle A[i]}A[i]的值增加delta,

那么,需要将{\displaystyle BIT[i]}BIT[i]覆盖的区间包含{\displaystyle A[i]}A[i]的值都加上delta.

这个过程可以写成递归,或者普通的循环.

需要计算的次数与数据规模N的二进制位数有关,即这部分的时间复杂度是O(LogN)

修改函数的C++写法

void edit(int i, int delta)
{
    for (int j = i; j <= MAX_N; j += lowbit(j))
        BIT[j] += delta;
}

求和[编辑]

假设我们需要计算{\displaystyle \sum _{i=1}^{k}A_{i}}\sum _{{i=1}}^{{k}}A_{i}的值.

  1. 首先,将ans初始化为0,将i初始化为k.
  2. 将ans的值加上BIT[i]
  3. 将i的值减去lowbit(i)
  4. 重复步骤2~3,直到i的值变为0

求和函数的C/C++写法

int sum (int k)
{
    int ans = 0;
    for (int i = k; i > 0; i -= lowbit(i))
        ans += BIT[i];
    return ans;
}

复杂度[编辑]

初始化复杂度最优为{\displaystyle O(N)}O (N)

单次询问复杂度{\displaystyle O(\log N)}O(\log N),其中N为数组大小

单次修改复杂度{\displaystyle O(\log N)}O(\log N),其中N为数组大小

空间复杂度{\displaystyle O(N)}O (N)

Applications [ edit ]

Seeking inverse number [5] [ Edit ]

Reverse number is a series of numbers in front of it than it has a large number. The reverse order number 4312 is 1 + 0 + 2 + 2 = 5.

Traversing from the first number, each time in Fenwick tree in the number of inquiries number greater than the current number and add a counter, after the current element is added Fenwick tree.



Published 37 original articles · won praise 12 · views 6535

Guess you like

Origin blog.csdn.net/weixin_38960774/article/details/79404701