vendredi 24 juillet 2015

Why does my SegmentTree class produce weird results on multiple tests?

I've recently been working on solving the SPOJ problem HORRIBLE, and have created a segment tree using lazy propagation for that. I received a WA from the judge, and decided to put my code to little tests, and, when I used the case given in sample input twice, it give me a weird value. I have checked and re-checked, it doesn't seem that any of the variable initialisations are acting problematic. So, I simply decided to pull the values in the vector, which was filled with zeroes(as expected), and putting rest to the theory of initialisation problems. One possible error could be due to C++11 class initialisations, which I'm not sure about.

Below is my code:

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

typedef long long int lli;
const long long int neginf = -17070509*17070509;

class leaf {
public:
    lli val = 0, lazy = 0;  
};

class SegmentTree {
private:
    int n;
    vector<leaf> st;
    inline int left(int node) { return node<<2; }
    inline int right(int node) { return (node<<2)+1;}

    void upd(int node, int L, int R, int v)
    {
        st[node].val += (R-L+1)*v;
        st[node].lazy += v;
    }

    void lazyupd(int node, int L, int R, int a, int b, int changed)
    {
        if(a <= L && b >= R)
        {
            upd(node, L, R, changed);
        }
        else if(a > R || b < L) return;
        else
        {
            lazyupd(left(node), L, (L+R)/2, a, b, changed);
            lazyupd(right(node), (L+R)/2+1, R, a, b, changed);

            st[node].val = st[left(node)].val + st[right(node)].val;
        }
    }

    void lazyshift(int node, int L, int R)
    {
        upd(left(node), L, (L+R)/2, st[node].lazy);
        upd(right(node), (L+R)/2+1, R, st[node].lazy);
        st[node].lazy = 0;
    }

    lli RSQ(int node, int L, int R, int a, int b)
    {
        if(a <= L && b >= R) return st[node].val;
        else if(a > R || b < L) return neginf;
        else
        {
            lazyshift(node, L, R);

            int p1 = RSQ(left(node), L, (L+R)/2, a, b);
            int p2 = RSQ(right(node), (L+R)/2+1, R, a, b);

            if(p1 == neginf) return p2;
            else if(p2 == neginf) return p1;
            else return p1+p2;
        }
    }
public:
    SegmentTree(int x)
    {
        n = x;
        st.clear();
        st.resize(4*n);
        //for(int i = 1;i < 4*n;i++) cout << st[i].val << " " << st[i].lazy << endl;
    }

    void lazyupdintfc(int a, int b, int v)
    {
        lazyupd(1, 0, n-1, a, b, v);
    }

    lli RSQintfc(int a, int b)
    {
        return RSQ(1, 0, n-1, a, b);
    }
};

int main(void)
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n, q, type,a, b, v;
        scanf("%d%d", &n, &q);
        SegmentTree TT(n);
        while(q--)
        {
            scanf("%d%d%d", &type, &a, &b);
            if(type) printf("%lld\n", TT.RSQintfc(a-1, b-1));
            else 
            {
                scanf("%d", &v);
                TT.lazyupdintfc(a-1, b-1, v);
            }
        }
    }
}

And this is the test case I used:

2
8 6
0 2 4 26
0 4 8 80
0 4 5 20
1 8 8 
0 5 7 14
1 4 8
8 6
0 2 4 26
0 4 8 80
0 4 5 20
1 8 8 
0 5 7 14
1 4 8

It's the exact same case, repeated twice, and these are the results:

80
508
206
686

Can anyone figure out why this is happening? even though all the initialisations are alright ? The results may also be seen at IdeOne

Aucun commentaire:

Enregistrer un commentaire