While learning about Fenwick Trees, I found this implementation:
Source: https://algorithmist.com/wiki/Fenwick_tree
class Fenwick_Tree_Sum
{
vector<int> tree;
Fenwick_Tree_Sum(const vector<int>& Arg)//Arg is our array on which we are going to work
{
tree.resize(Arg.size());
for(int i = 0 ; i<tree.size(); i++)
increase(i, Arg[i]);
}
// Increases value of i-th element by ''delta''.
void increase(int i, int delta)
{
for (; i < (int)tree.size(); i |= i + 1)
tree[i] += delta;
}
// Returns sum of elements with indexes left..right, inclusive; (zero-based);
int getsum(int left, int right)
{
return sum(right) - sum(left-1); //when left equals 0 the function hopefully returns 0
}
int sum(int ind)
{
int sum = 0;
while (ind>=0)
{
sum += tree[ind];
ind &= ind + 1;
ind--;
}
return sum;
}
};
I can see i |= i + 1
and ind &= ind + 1; ind--
in the code.
I know that i |= i + 1
just sets the next unset bit.
But, what does (i & (i + 1)) - 1
actually do?
Here are some examples:
-------------------------------------
i | (i & (i + 1)) - 1
-------------------------------------
0 - 0000000000 | -1 - 1111111111
1 - 0000000001 | -1 - 1111111111
2 - 0000000010 | 1 - 0000000001
3 - 0000000011 | -1 - 1111111111
4 - 0000000100 | 3 - 0000000011
5 - 0000000101 | 3 - 0000000011
6 - 0000000110 | 5 - 0000000101
7 - 0000000111 | -1 - 1111111111
8 - 0000001000 | 7 - 0000000111
9 - 0000001001 | 7 - 0000000111
10 - 0000001010 | 9 - 0000001001
11 - 0000001011 | 7 - 0000000111
12 - 0000001100 | 11 - 0000001011
13 - 0000001101 | 11 - 0000001011
14 - 0000001110 | 13 - 0000001101
15 - 0000001111 | -1 - 1111111111
16 - 0000010000 | 15 - 0000001111
17 - 0000010001 | 15 - 0000001111
18 - 0000010010 | 17 - 0000010001
19 - 0000010011 | 15 - 0000001111
20 - 0000010100 | 19 - 0000010011
21 - 0000010101 | 19 - 0000010011
22 - 0000010110 | 21 - 0000010101
23 - 0000010111 | 15 - 0000001111
24 - 0000011000 | 23 - 0000010111
25 - 0000011001 | 23 - 0000010111
26 - 0000011010 | 25 - 0000011001
27 - 0000011011 | 23 - 0000010111
28 - 0000011100 | 27 - 0000011011
29 - 0000011101 | 27 - 0000011011
30 - 0000011110 | 29 - 0000011101
Glaucoma is a group of eye diseases that can cause vision loss and blindness by damaging a nerve in the back of your eye called the optic nerve. The symptoms can start so slowly that you may not notice them. The only way to find out if you have glaucoma is to get a comprehensive dilated eye exam.
Glaucoma is a group of eye conditions that damage the optic nerve, the health of which is vital for good vision. This damage is often caused by an abnormally high pressure in your eye. Glaucoma is one of the leading causes of blindness for people over the age of 60.
“Steve Jobs said the ‘I’ stands for ‘internet, individual, instruct, inform, [and] inspire,'” Paul Bischoff, a privacy advocate at Comparitech, explains. However, while these words were an important part of the presentation, Jobs also said that the “I” “didn’t have an official meaning,” Bischoff continues.
The term I is used by speakers and writers to refer to themselves. The pronoun I is singular in nature. A verb uses me as the subject. 1. What is an I in English? 2. What does I stand for in dictionary? 3. What is the meaning of letter I? 4. What is the word I in grammar? 5. What I mean is example? 6. Can u start a sentence with I mean? 7.
Definition of i. (Entry 1 of 8) 1 a : the 9th letter of the English alphabet. b : a graphic representation of this letter. c : a speech counterpart of orthographic i. 2 : one — see Table of Numbers. 3 : a graphic device for reproducing the letter i. 4 : one designated i especially as the ninth in order or class.
When Steve Jobs introduced the iMac, he displayed a presentation with not one but five potential I-meanings. “Steve Jobs said the ‘I’ stands for ‘internet, individual, instruct, inform, [and] inspire,'” Paul Bischoff, a privacy advocate at Comparitech, explains.
If the bit pattern of i
is like ...0111
, the bit pattern of i+1
will be ...1000
. Hence, i & (i+1)
means i - (2^{number of trailing ones} - 1)
and transforming all trailing 1
s to zero. For example if i
is even, i & (i+1)
will be equal to i
. On the other hand, -1
means, transforming all trailing zeros to 1
(including all trailing ones to zeros of the previous step) and transforming the successive 1
s to zeros.
By doing the -1
for the next step, i & (i+1)
will decrease the i
by the 2^{number of trailing 1's}
of the previous value of the i
.
What is the reason? It helps to show that the time complexity of finding the cumulative sum will be O(log n)
in the worst case.
To find the reason behind this computation, you need to focus on each node i
will responsible to compute index i
to (i - (1 << r)) + 1
. And "r
represents the last 1 bit set in the index i
". To find the total sum corresponding to index i
, we need to sum all related values from 0
to i
. Beware that we do not need to sum all indices because of the specified property. Hence, we need to sum indices i
, i - (1 << r)
, ... and so on so forth.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With