The RMQ problem can be extended like so:
Given is an array of n
integers A
.
query(x, y): given two integers 1 ≤ x
, y
≤ n
, find the minimum of A[x], A[x+1], ... A[y]
;
update(x, v): given an integer v
and 1 ≤ x
≤ n
do A[x] = v
.
This problem can be solved in O(log n)
for both operations using segment trees.
This is an efficient solution on paper, but in practice, segment trees involve a lot of overhead, especially if implemented recursively.
I know for a fact that there is a way to solve the problem in O(log^2 n)
for one (or both, I'm not sure) of the operations, using binary indexed trees (more resources can be found, but this and this are, IMO, the most concise and exhaustive, respectively). This solution, for values of n
that fit into memory, is faster in practice, because BITs have a lot less overhead.
However, I do not know how the BIT structure is used to perform the given operations. I only know how to use it to query an interval sum for example. How can I use it to find the minimum?
If it helps, I have code that others have written that does what I am asking for, but I cannot make sense of it. Here is one such piece of code:
int que( int l, int r ) {
int p, q, m = 0;
for( p=r-(r&-r); l<=r; r=p, p-=p&-p ) {
q = ( p+1 >= l ) ? T[r] : (p=r-1) + 1;
if( a[m] < a[q] )
m = q;
}
return m;
}
void upd( int x ) {
int y, z;
for( y = x; x <= N; x += x & -x )
if( T[x] == y ) {
z = que( x-(x&-x) + 1, x-1 );
T[x] = (a[z] > a[x]) ? z : x;
}
else
if( a[ T[x] ] < a[ y ] )
T[x] = y;
}
In the above code, T
is initialized with 0, a
is the given array, N
its size (they do indexing from 1 for whatever reason) and upd
is called at first for every read value. Before upd
is called a[x] = v
is executed.
Also, p & -p
is the same as the p ^ (p & (p - 1))
in some BIT sources and indexing starts from 1 with the zero element initialized to infinity.
Can anyone explain how the above works or how I could solve the given problem with a BIT?
for( y = x; x <= N; x += x & -x )
this is deep. BTW what isT[]
? BTW2: I'm not sure if this should befor( y = x; x < N; x += x & -x )
BTW3: what isN
? – wildplasserfor
is actually quite standard for a BIT.T
seems to be where the BIT information is actually held. As forN
, that isn
in my problem statement, I will edit that in. – IVlad