Search code examples
c++algorithmsegment-treermq

Bug in RMQ Segment Tree


I am trying to build a Segment Tree for performing RMQ. Somehow, no matter what range I query it will return me 0.

For example, my array is [ 1,2,3,4,5,6,7,8,9,10 ]. RMQ from index 3 to 5 should give 4. But my code keeps outputting 0.

My code:

#include<bits/stdc++.h>

using namespace std;

#define ll long long

ll N, st[2*100000], arr[100000];

void build(int r, int lo,int hi) {
    if(lo==hi) {
        st[r] = arr[lo];
    } else {
        build(r<<1,lo,(lo+hi)>>1);
        build((r<<1)|1,((lo+hi)>>1)+1,hi);
        st[r] = min(st[r<<1],st[(r<<1)|1]);
    }
}

void update(int r,int lo,int hi,ll val,int i) {
    if(lo==hi) {
        st[r] = val;
    } else {
        int mid = (lo+hi)>>1;
        if(lo <= i && i <= mid) {
            update(r<<1,lo,mid,val,i);
        } else {
            update((r<<1)|1,mid+1,hi,val,i);
        }
        st[r] = min(st[r<<1],st[(r<<1)|1]);
    }   
}

ll query(int r,int lo,int hi,int a,int b) {
    if(lo > b || hi < a) {
        return LLONG_MAX;
    } else if(lo <= a && hi >= b) {
        return st[r];
    } else {
        int mid = (lo+hi)>>1;
        return st[r] = min(query(r<<1,lo,mid,a,mid),query((r<<1)|1,mid+1,hi,mid+1,b));
    }
}

int main(void) {
    for(int i = 0; i <= 10; i++) arr[i] = i;
    build(1,0,10);
    cout << query(1,0,10,3,5) << endl;
    return 0;
}

Edit:

Thanks for all the help. Like what the answer below mentioned, my query range was wrong. There are also 2 bugs apart from this:

if(lo <= a && hi >= b) should be (a <= lo && b >= hi)

and

return st[r] = min(query(r<<1,lo,mid,a,mid),query((r<<1)|1,mid+1,hi,mid+1,b));

should be

return min(query(r<<1,lo,mid,a,mid),query((r<<1)|1,mid+1,hi,mid+1,b));

since I am only making queries and should not be modifying the tree.


Solution

  • This line of code:

    return st[r] = min(query(r<<1,lo,mid,a,mid),query((r<<1)|1,mid+1,hi,mid+1,b));
    

    why are you changing your a and b in short you are changing your query in every recursive calls. it should be

     return st[r] = min(query(r<<1,lo,mid,a,b),query((r<<1)|1,mid+1,hi,a,b));
    

    And Also your update function is wrong:

    Check Here