Search code examples
c++segment-tree

exception thrown while passing parameters


I am getting error Exception thrown at 0x009523B9 in Project5.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00E42ED4). in the below program

test case:

5

1 2 3 4 5

1

Q 2 4

I was getting error when executing this line struct node query(int index, int start, int endv, int l, int r) that is when query function was called for first time in main

The parameter were like at the time of exception thrown should be query(0,0,4,1,3)

but they are automatically changing to query(0,1,1,1,3) where I am doing wrong

This was the question based on segment trees spoj KGSS

#include<iostream>
#include<algorithm>
#include<climits>
#pragma warning(disable:4996)    //disable scanf warning 
using namespace std;

struct node {
    long long int maxsum;
    long long int maxnum;
};
long long int a[100];
struct node tree[100];
void build(int index, int start, int endv) {
    if (start == endv) {
        tree[index].maxsum = a[start];
        tree[index].maxnum = a[start];
    }
    else {
        int mid = (start + endv) / 2;
        build(2 * index + 1, start, mid);
        build(2 * index + 2, mid + 1, endv);

        tree[index].maxnum = max(tree[2 * index + 1].maxnum, tree[2 * index + 2].maxnum);
        tree[index].maxsum = max(tree[2 * index + 1].maxnum + tree[2 * index + 2].maxnum, max(tree[2 * index + 1].maxsum, tree[2 * index + 2].maxsum));
    }
}

struct node query(int index, int start, int endv, int l, int r) {

    struct node result;

    result.maxnum = INT_MIN;
    result.maxsum = INT_MIN;

    if (l > endv || r < start)
        return result;
    int mid = (start + endv) / 2;
    struct node left, right;
    left = query(index, start, mid, l, r);
    right = query(index, mid + 1, endv, l, r);

    tree[index].maxnum = max(left.maxnum, right.maxnum);
    tree[index].maxsum = max(left.maxnum + right.maxnum, max(left.maxsum, right.maxsum));

    return tree[index];
}

void update(int index, int start, int endv, int aidx, long long int value) {


    if (start == endv) {
        a[aidx] = value;
        tree[index].maxsum = value;
        tree[index].maxnum = value;
    }
    else {

        int mid = (start + endv) / 2;
        if (aidx <= mid) {
            update(2 * index + 1, start, mid, aidx, value);
        }
        else {
            update(2 * index + 2, mid + 1, endv, aidx, value);
        }

        tree[index].maxnum = max(tree[2 * index + 1].maxnum, tree[2 * index + 2].maxnum);
        tree[index].maxsum = max(tree[2 * index + 1].maxnum + tree[2 * index + 2].maxnum, max(tree[2 * index + 1].maxsum, tree[2 * index + 2].maxsum));
    }
}

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    build(0, 0, n - 1);
    //for(int i = 0)
    int q;
    cin >> q;
    for (int i = 0; i < q; i++) {
        int l, r;
        char ap;
        cin >> ap >> l >> r;
        if (ap == 'U') {
            update(0, 0, n - 1, l - 1, r);
        }
        else {
            struct node temp = query(0, 0, n - 1, l - 1, r - 1);
            printf("%lld\n", temp.maxsum);
        }
    }

}

NOTE -> I used result.maxnum = INT_MIN; result.maxsum = INT_MIN;

in query function and result.maxnum and result.maxsum are of long long int types and i am assigning INT_MIN to them.

This is because some times from both side of the recursion i get min value and on adding these values and storing them on a int variable leads to integer overflow thats why i used long long int can someone provide way for handling this situation or this is ok


Solution

  •     scanf("%d", &a[i]);
    

    is incorrect when the type of a[i] is long long int. It's also not a good idea to mix C++ I/O with C I/o. There's nothing wrong with

    cin >> a[i];
    

    But the main problem is that you have a stack overflow. In your example

    query(0,0,4,1,3) ->
     query(0,0,2,1,3) ->
      query(0,0,1,1,3) ->
       query(0,0,0,1,3) ->
        return result
       query(0,1,1,1,3) ->
        query(0,1,1,1,3) ->
         query(0,1,1,1,3) ->
          query(0,1,1,1,3) ->
           query(0,1,1,1,3) ->
            query(0,1,1,1,3) ->
             query(0,1,1,1,3) ->
              BOOM!! stack overflow
    

    Not quite sure what to do to fix it, since I don't understand the code. I would have thought something like

    if (start >= endv)
        return result;
    

    at the beginning would help but I'm not really sure.