Esempio n. 1
0
 void initialize(vui_t const& elems) {
     if (elems.empty()) {
         this->initialize(0);
     }
     else {
         this->initialize(elems.size());
         this->_init(0, 0, elems.size() - 1, elems);
     }
 }
    void initialize(vui_t const& elems) {

	this->data = elems;
        this->len = elems.size();
        this->repr.clear();

        DCERR("len: "<<this->len<<endl);

        const size_t ntables = log2(this->len) + 1;
        this->repr.resize(ntables);

        DCERR("ntables: "<<ntables<<endl);

        this->repr[0].resize(this->len);
        for (size_t i = 0; i < this->len; ++i) {
	    // This is the identity mapping, since the MAX element in
	    // a range of length 1 is the element itself.
            this->repr[0][i] = i;
        }

        for (size_t i = 1; i < ntables; ++i) {
	    /* The previous 'block size' */
            const uint_t pbs = 1<<(i-1);

            /* bs is the 'block size'. i.e. The number of elements
	     * from the data that are used to computed the max value
	     * and store it at repr[i][...].
	     */
            const uint_t bs = 1<<i;

	    /* The size of the vector at repr[i]. We need to resize it
	     * to this size.
	     */
            const size_t vsz = this->len - bs + 1;

	    DCERR("starting i: "<<i<<" bs: "<<bs<<endl);

            this->repr[i].resize(vsz);

            // cerr<<"i: "<<i<<", vsz: "<<vsz<<endl;

            vui_t& curr = this->repr[i];
            vui_t& prev = this->repr[i - 1];

            for (size_t j = 0; j < vsz; ++j) {
                // 'j' is the starting index of a block of size 'bs'
		const uint_t prev_elem1 = data[prev[j]];
		const uint_t prev_elem2 = data[prev[j+pbs]];
                if (prev_elem1 > prev_elem2) {
                    curr[j] = prev[j];
                }
                else {
                    curr[j] = prev[j+pbs];
                }
                // cerr<<"curr["<<j<<"] = "<<curr[j].first<<endl;
            }
            // cerr<<"done with i: "<<i<<endl;
        }
        // cerr<<"initialize() completed"<<endl;
    }
Esempio n. 3
0
/* This is a destructive function - one which deletes the tree rooted
 * at node n
 */
void
euler_tour(BinaryTreeNode *n,
           vui_t &output, /* Where the output is written. Should be empty */
           vui_t &levels, /* Where the level for each node is written. Should be empty */
           vui_t &mapping /* mapping stores representative
                             indexes which maps from the original index to the index
                             into the euler tour array, which is a +- RMQ */,
           vui_t &rev_mapping /* Reverse mapping to go from +-RMQ
				 indexes to user provided indexes */,
           int level = 1) {
    DPRINTF("euler_tour(%d, %d)\n", n?n->data:-1, n?n->index:-1);
    if (!n) {
        return;
    }
    output.push_back(n->data);
    mapping[n->index] = output.size() - 1;
    DPRINTF("mapping[%d] = %d\n", n->index, mapping[n->index]);
    rev_mapping.push_back(n->index);
    levels.push_back(level);
    if (n->left) {
        euler_tour(n->left, output, levels, mapping, rev_mapping, level+1);
        output.push_back(n->data);
        rev_mapping.push_back(n->index);
        levels.push_back(level);
    }
    if (n->right) {
        euler_tour(n->right, output, levels, mapping, rev_mapping, level+1);
        output.push_back(n->data);
        rev_mapping.push_back(n->index);
        levels.push_back(level);
    }
    // We don't delete the node here since the clear() function on the
    // SimpleFixedObjectAllocator<BinaryTreeNode> will take care of
    // cleaning up the associated memory.
    //
    // delete n;
}
Esempio n. 4
0
    void initialize(vui_t const& elems) {

        this->len = elems.size();
        this->repr.clear();

        cerr<<"len: "<<this->len<<endl;

        const size_t ntables = log2(this->len) + 1;
        this->repr.resize(ntables);

        cerr<<"ntables: "<<ntables<<endl;

        this->repr[0].resize(this->len);
        for (size_t i = 0; i < this->len; ++i) {
            this->repr[0][i] = std::make_pair(elems[i], i);
        }

        for (size_t i = 1; i < ntables; ++i) {
            // bs is the 'block size'. i.e. Number of element in the
            // array this->repr[i]
            // cerr<<"starting i: "<<i<<endl;
            const uint_t pbs = 1<<(i-1);
            const uint_t bs = 1<<i;
            const size_t vsz = this->len - bs + 1;

            this->repr[i] = vpui_t();
            this->repr[i].resize(vsz);

            // cerr<<"i: "<<i<<", vsz: "<<vsz<<endl;

            vpui_t& curr = this->repr[i];
            vpui_t& prev = this->repr[i - 1];

            for (size_t j = 0; j < vsz; ++j) {
                // 'j' is the starting index of a block of size 'bs'
                if (prev[j].first > prev[j+pbs].first) {
                    curr[j] = prev[j];
                }
                else {
                    curr[j] = prev[j+pbs];
                }
                // cerr<<"curr["<<j<<"] = "<<curr[j].first<<endl;
            }
            // cerr<<"done with i: "<<i<<endl;
        }
        // cerr<<"initialize() completed"<<endl;
    }
Esempio n. 5
0
    void initialize(vui_t const& elems) {
        len = elems.size();

        if (len < MIN_SIZE_FOR_BENDER_RMQ) {
            st.initialize(elems);
            return;
        }

        vui_t levels;
        SimpleFixedObjectAllocator<BinaryTreeNode> alloc(len);

        euler.reserve(elems.size() * 2);
        mapping.resize(elems.size());
        BinaryTreeNode *root = make_cartesian_tree(elems, alloc);

        DPRINTF("GraphViz (paste at: http://ashitani.jp/gv/):\n%s\n", toGraphViz(NULL, root).c_str());

        euler_tour(root, euler, levels, mapping, rev_mapping);

        root = NULL; // This tree has now been deleted
        alloc.clear();

        assert_eq(levels.size(), euler.size());
        assert_eq(levels.size(), rev_mapping.size());

        uint_t n = euler.size();
        lgn_by_2 = log2(n) / 2;
        _2n_lgn  = n / lgn_by_2 + 1;

        DPRINTF("n = %u, lgn/2 = %d, 2n/lgn = %d\n", n, lgn_by_2, _2n_lgn);
        lt.initialize(lgn_by_2);

        table_map.resize(_2n_lgn);
        vui_t reduced;

        for (uint_t i = 0; i < n; i += lgn_by_2) {
            uint_t max_in_block = euler[i];
            int bitmap = 1L;
            DPRINTF("Sequence: (%u, ", euler[i]);
            for (int j = 1; j < lgn_by_2; ++j) {
                int curr_level, prev_level;
                uint_t value;
                if (i+j < n) {
                    curr_level = levels[i+j];
                    prev_level = levels[i+j-1];
                    value = euler[i+j];
                } else {
                    curr_level = 1;
                    prev_level = 0;
                    value = 0;
                }

                const uint_t bit = (curr_level < prev_level);
                bitmap |= (bit << j);
                max_in_block = std::max(max_in_block, value);
                DPRINTF("%u, ", value);
            }
            DPRINTF("), Bitmap: %s\n", bitmap_str(bitmap).c_str());
            table_map[i / lgn_by_2] = bitmap;
            reduced.push_back(max_in_block);
        }

        DPRINTF("reduced.size(): %u\n", reduced.size());
        st.initialize(reduced);
        DCERR("initialize() completed"<<endl);
    }