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; }
/* 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; }
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; }
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); }