void construct_supercartesian_tree_bp(const t_rac& vec, bit_vector& bp, const bool minimum = true) { typedef typename t_rac::size_type size_type; bp.resize(2 * vec.size()); // resize bit vector for balanaced parantheses to 2 n bits util::set_to_value(bp, 0); std::stack<typename t_rac::value_type> vec_stack; size_type k = 0; for (size_type i = 0; i < vec.size(); ++i) { typename t_rac::value_type l = vec[i]; if (minimum) { while (vec_stack.size() > 0 and l < vec_stack.top()) { vec_stack.pop(); ++k; /*bp[k++] = 0; bp is already initialized to zero*/ // writing a closing parenthesis } } else { while (vec_stack.size() > 0 and l > vec_stack.top()) { vec_stack.pop(); ++k; /*bp[k++] = 0; bp is already initialized to zero*/ // writing a closing parenthesis } } vec_stack.push(l); bp[k++] = 1; // writing an opening parenthesis } while (vec_stack.size() > 0) { vec_stack.pop(); bp[k++] = 0; // writing a closing parenthesis } assert(k == 2 * vec.size()); }
bit_vector construct_supercartesian_tree_bp_succinct(const t_rac& vec, const bool minimum=true) { typedef typename t_rac::size_type size_type; bit_vector bp(2*vec.size(), 0); // initialize result if (vec.size() > 0) { sorted_stack_support vec_stack(vec.size()); size_type k=0; if (minimum) { bp[k++] = 1; for (size_type i=1; i < vec.size(); ++i) { if (vec[i] < vec[i-1]) { ++k; while (vec_stack.size() > 0 and vec[i] < vec[vec_stack.top()]) { vec_stack.pop(); ++k; // writing a closing parenthesis, bp is already initialized to zero } } else { vec_stack.push(i-1); // "lazy stack" trick: speed-up approx. 25% } bp[k++] = 1; // writing an opening parenthesis } } else { // no "lazy stack" trick used here for (size_type i=0; i < vec.size(); ++i) { while (vec_stack.size() > 0 and vec[i] > vec[vec_stack.top()]) { vec_stack.pop(); ++k; /*bp[k++] = 0; bp is already initialized to zero*/ // writing a closing parenthesis } vec_stack.push(i); bp[k++] = 1; // writing an opening parenthesis } } } return bp; }
rmq_support_sparse_table(const t_rac* v=nullptr):m_v(v), m_k(0) { if (m_v == nullptr) return; const size_type n = m_v->size(); if (n < 2) // for n<2 the queries could be answerd without any table return; size_type k=0; while (2*(1ULL<<k) < n) ++k; // calculate maximal if (!(m_table == nullptr)) delete [] m_table; m_table = new int_vector<>[k]; m_k = k; for (size_type i=0; i<k; ++i) { m_table[i] = int_vector<>(n-(1<<(i+1))+1, 0, i+1); } for (size_type i=0; i<n-1; ++i) { if (!mm_trait::compare((*m_v)[i], (*m_v)[i+1])) m_table[0][i] = 1; } for (size_type i=1; i<k; ++i) { for (size_type j=0; j<m_table[i].size(); ++j) { m_table[i][j] = mm_trait::compare((*m_v)[j+m_table[i-1][j]], (*m_v)[j+(1<<i)+m_table[i-1][j+(1<<i)]]) ? m_table[i-1][j] : (1<<i)+m_table[i-1][j+(1<<i)]; } } }
size_type size()const { if (m_v == nullptr) return 0; else return m_v->size(); }