void construct_supercartesian_tree_bp_succinct(const RandomAccessContainer& vec, bit_vector& bp, const bool minimum=true)
{
    typedef typename RandomAccessContainer::size_type size_type;
    bp.resize(2*vec.size());      // resize bit vector for balanced parentheses to 2 n bits
    if (vec.size() > 0) {
        util::set_to_value(bp, 0);
        sorted_stack_support vec_stack(vec.size()); // <- das ist ein Problem fuer int_vector_file_buffer

        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 ca. 25%
                }
                bp[k++] = 1; // writing an opening  parenthesis
            }
            /*
            vec_stack.push(0);
            bp[k++] = 1;
            for(size_type i=1,j, start_run=1; i < vec.size(); ++i){
            	if( vec[i] < vec[i-1] ){
            		j = i;
            		while( --j >= start_run and vec[i] < vec[j]) ++k;
            		while(start_run <= j){	// auf den stack pushen
            			vec_stack.push(start_run++);
            		}
            		while( vec_stack.size() > 0 and vec[i] < vec[vec_stack.top()] ){
            			vec_stack.pop(); ++k;
            		}
            		start_run = i;
            	}
            	bp[k++] = 1;
            }
            */
        } else {
            // hier noch ohne "lazy stack" trick
            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
            }
        }
#ifdef SDSL_DEBUG
        // not necessary as bp is already initialized to zero
        while (!vec_stack.empty()) {
            vec_stack.pop();
            bp[k++] = 0; // writing a closing parenthesis
        }
        assert(k == 2*vec.size());
#endif
    }
}
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;
}
void construct_supercartesian_tree_bp_succinct2(const RandomAccessContainer& vec, bit_vector& bp, const bool minimum=true)
{
    typedef typename RandomAccessContainer::size_type size_type;
    bp.resize(2*vec.size());      // resize bit vector for balanced parentheses to 2 n bits
    util::set_to_value(bp, 0);
    sorted_stack_support vec_stack(vec.size()); // <- das ist ein Problem fuer int_vector_file_buffer

    size_type k=0;
//	uint64_t wbuf=0;
    for (size_type i=0/*, cnt64=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
        while (i+1 < vec.size() and vec[i+1] >= vec[i]) {
            vec_stack.push(++i);
            bp[k++];
        }
    }
#ifdef SDSL_DEBUG
// not neccessary as bp is already initialized to zero
    while (vec_stack.size() > 0) {
        vec_stack.pop();
        bp[k++] = 0; // writing a closing parenthesis
    }
    assert(k == 2*vec.size());
#endif
}
bit_vector::size_type construct_supercartesian_tree_bp_succinct_and_first_child(
int_vector_buffer<t_width>& lcp_buf, bit_vector& bp, bit_vector& bp_fc, const bool minimum = true)
{
	typedef bit_vector::size_type size_type;
	size_type					  n = lcp_buf.size();
	bp.resize(2 * n); // resize bit vector for balanced parentheses to 2 n bits
	bp_fc.resize(n);
	if (n == 0) // if n == 0 we are done
		return 0;
	size_type fc_cnt = 0; // first child counter
	util::set_to_value(bp, 0);
	util::set_to_value(bp_fc, 0);
	sorted_multi_stack_support vec_stack(n);

	size_type k	= 0;
	size_type k_fc = 0; // first child index
	if (minimum) {
		// no "lazy stack" trick used here
		for (size_type i = 0, x; i < n; ++i) {
			x = lcp_buf[i];
			while (!vec_stack.empty() and x < vec_stack.top()) {
				if (vec_stack.pop()) {
					bp_fc[k_fc] = 1;
					++fc_cnt;
				}
				++k;	// writing a closing parenthesis, bp is already initialized to zeros
				++k_fc; // write a bit in first_child
			}
			vec_stack.push(x);
			bp[k++] = 1; // writing an opening parenthesis
		}

	} else {
		// no "lazy stack" trick used here
		for (size_type i = 0, x; i < n; ++i) {
			x = lcp_buf[i];
			while (!vec_stack.empty() and x > vec_stack.top()) {
				if (vec_stack.pop()) {
					bp_fc[k_fc] = 1;
					++fc_cnt;
				}
				++k;	// writing a closing parenthesis, bp is already initialized to zeros
				++k_fc; // write a bit in first_child
			}
			vec_stack.push(x);
			bp[k++] = 1; // writing an opening parenthesis
		}
	}
	while (!vec_stack.empty()) {
		if (vec_stack.pop()) {
			bp_fc[k_fc] = 1;
			++fc_cnt;
		}
		// writing a closing parenthesis in bp, not necessary as bp is initialized with zeros
		++k;
		++k_fc;
	}
	return fc_cnt;
}
bit_vector::size_type construct_first_p_index(int_vector_file_buffer<fixedIntWidth>& lcp_buf, bit_vector& bp, const bool minimum=true)
{
    typedef bit_vector::size_type size_type;
    size_type nr_of_first_indices = 0;
    lcp_buf.reset();
    size_type n = lcp_buf.int_vector_size;

    bp = bit_vector(n, 0);
    sorted_multi_stack_support vec_stack(n);
    size_type k=0;

    if (minimum) {
        for (size_type i = 0, r_sum = 0, r = lcp_buf.load_next_block(),x; r_sum < n;) {
            for (; i<r_sum+r; ++i) {
                x = lcp_buf[i-r_sum];
                while (!vec_stack.empty() and x < vec_stack.top()) {
                    if (vec_stack.pop()) {
                        bp[k] = 1;
                        ++nr_of_first_indices;
                    }
                    ++k;
                }
                vec_stack.push(x);
            }
            r_sum += r; r = lcp_buf.load_next_block();
        }
    } else {
        for (size_type i = 0, r_sum = 0, r = lcp_buf.load_next_block(),x; r_sum < n;) {
            for (; i<r_sum+r; ++i) {
                x = lcp_buf[i-r_sum];
                while (!vec_stack.empty() and x > vec_stack.top()) {
                    if (vec_stack.pop()) {
                        bp[k] = 1;
                        ++nr_of_first_indices;
                    }
                    ++k;
                }
                vec_stack.push(x);
            }
            r_sum += r; r = lcp_buf.load_next_block();
        }
    }

    while (!vec_stack.empty()) {
        if (vec_stack.pop()) {
            bp[k] = 1;
            ++nr_of_first_indices;
        }
        ++k;
    }
//	assert( k == vec.size() );
    return nr_of_first_indices;
}
void construct_supercartesian_tree_bp_succinct(int_vector_file_buffer<fixedIntWidth>& lcp_buf, bit_vector& bp, const bool minimum=true)
{
    typedef int_vector_size_type size_type;
    lcp_buf.reset();
    size_type n = lcp_buf.int_vector_size;
    bp.resize(2*n);      // resize bit vector for balanced parentheses to 2 n bits
    if (n == 0)	// if n == 0 we are done
        return;
    util::set_to_value(bp, 0);
    sorted_multi_stack_support vec_stack(n);

    size_type k=0;
    if (minimum) {
        bp[k++] = 1;
        size_type r = lcp_buf.load_next_block();
        size_type last = lcp_buf[0];
        for (size_type i=1, r_sum = 0, x; r_sum < n;) {
            for (; i < r_sum +r; ++i) {
                x = lcp_buf[i-r_sum];
                if (x < last) {
                    ++k; // writing a closing parenthesis for last
                    while (!vec_stack.empty() and x < vec_stack.top()) {
                        vec_stack.pop(); ++k; // writing a closing parenthesis, bp is already initialized to zeros
                    }
                } else {
                    vec_stack.push(last); // "lazy stack" trick: Beschleunigung: ca 25 %
                }
                bp[k++] = 1; // writing an opening parenthesis
                last = x;
            }
            r_sum += r; r = lcp_buf.load_next_block();
        }
    } else {
        // hier noch ohne "lazy stack" trick
        for (size_type i=0, r_sum = 0, r = lcp_buf.load_next_block(), x; r_sum < n;) {
            for (; i < r_sum +r; ++i) {
                x = lcp_buf[i-r_sum];
                while (!vec_stack.empty() and x > vec_stack.top()) {
                    vec_stack.pop(); ++k; // writing a closing parenthesis, bp is already initialized to zeros
                }
                vec_stack.push(x);
                bp[k++] = 1; // writing an opening parenthesis
            }
            r_sum += r; r = lcp_buf.load_next_block();
        }
    }
}
typename RandomAccessContainer::size_type construct_first_p_index(const RandomAccessContainer& vec, bit_vector& bp, const bool minimum=true)
{
    typedef typename RandomAccessContainer::size_type size_type;
    size_type nr_of_first_indices = 0;
    bp = bit_vector(vec.size(), 0);
//	std::cerr<<"bp.size()="<<bp.size()<<std::endl;
    sorted_stack_support vec_stack(vec.size());
    size_type k=0;
    for (size_type i=0, t; i < vec.size(); ++i) {
        if (minimum) {
            while (vec_stack.size() > 0 and vec[i] < vec[vec_stack.top()]) {
                t = vec[vec_stack.top()];
                vec_stack.pop();
                if (vec_stack.size() == 0 or t != vec[vec_stack.top()]) {
                    bp[k] = 1;
                    ++nr_of_first_indices;
                }
                ++k;

            }
        } else {
            while (vec_stack.size() > 0 and vec[i] > vec[vec_stack.top()]) {
                t = vec[vec_stack.top()];
                vec_stack.pop();
                if (vec_stack.size() == 0 or t != vec[vec_stack.top()]) {
                    bp[k] = 1;
                    ++nr_of_first_indices;
                }
                ++k;
            }
        }
        vec_stack.push(i);
    }
    while (vec_stack.size() > 0) {
        size_type t = vec[vec_stack.top()];
        vec_stack.pop();
        if (vec_stack.size() == 0 or t != vec[vec_stack.top()]) {
            bp[k] = 1;
            ++nr_of_first_indices;
        }
        ++k;
    }
    assert(k == vec.size());
    return nr_of_first_indices;
}
bit_vector construct_supercartesian_tree_bp_succinct(int_vector_buffer<t_width>& lcp_buf,
													 const bool					 minimum = true)
{
	typedef bit_vector::size_type size_type;
	bit_vector					  bp(2 * lcp_buf.size(), 0); // initialize result
	if (lcp_buf.size() > 0) {
		sorted_multi_stack_support vec_stack(lcp_buf.size());

		size_type k = 0;
		if (minimum) {
			bp[k++]		   = 1;
			size_type last = lcp_buf[0];
			for (size_type i = 1, x; i < lcp_buf.size(); ++i) {
				x = lcp_buf[i];
				if (x < last) {
					++k; // writing a closing parenthesis for last
					while (!vec_stack.empty() and x < vec_stack.top()) {
						vec_stack.pop();
						++k; // writing a closing parenthesis, bp is already initialized to zeros
					}
				} else {
					vec_stack.push(last); // "lazy stack" trick: speed-up about 25 %
				}
				bp[k++] = 1; // writing an opening parenthesis
				last	= x;
			}
		} else {
			// no "lazy stack" trick use here
			for (size_type i = 0, x; i < lcp_buf.size(); ++i) {
				x = lcp_buf[i];
				while (!vec_stack.empty() and x > vec_stack.top()) {
					vec_stack.pop();
					++k; // writing a closing parenthesis, bp is already initialized to zeros
				}
				vec_stack.push(x);
				bp[k++] = 1; // writing an opening parenthesis
			}
		}
	}
	return bp;
}
int_vector_size_type construct_supercartesian_tree_bp_succinct_and_first_child(int_vector_file_buffer<fixedIntWidth>& lcp_buf, bit_vector& bp, bit_vector& bp_fc, const bool minimum=true)
{
    typedef int_vector_size_type size_type;
    lcp_buf.reset();
    size_type n = lcp_buf.int_vector_size;
    bp.resize(2*n);      // resize bit vector for balanaced parantheses to 2 n bits
    bp_fc.resize(n);
    if (n == 0)	// if n == 0 we are done
        return 0;
    size_type fc_cnt=0; // first child counter
    util::set_to_value(bp, 0);
    util::set_to_value(bp_fc, 0);
    sorted_multi_stack_support vec_stack(n);

    size_type k=0;
    size_type k_fc=0; // first child index
    if (minimum) {
        // hier noch ohne "lazy stack" trick
        for (size_type i=0, r_sum = 0, r = lcp_buf.load_next_block(), x; r_sum < n;) {
            for (; i < r_sum +r; ++i) {
                x = lcp_buf[i-r_sum];
                while (!vec_stack.empty() and x < vec_stack.top()) {
                    if (vec_stack.pop()) {
                        bp_fc[k_fc] = 1;
                        ++fc_cnt;
                    }
                    ++k; // writing a closing parenthesis, bp is already initialized to zeros
                    ++k_fc; // write a bit in first_child
                }
                vec_stack.push(x);
                bp[k++] = 1; // writing an opening parenthesis
            }
            r_sum += r; r = lcp_buf.load_next_block();
        }

    } else {
        // hier noch ohne "lazy stack" trick
        for (size_type i=0, r_sum = 0, r = lcp_buf.load_next_block(), x; r_sum < n;) {
            for (; i < r_sum +r; ++i) {
                x = lcp_buf[i-r_sum];
                while (!vec_stack.empty() and x > vec_stack.top()) {
                    if (vec_stack.pop()) {
                        bp_fc[k_fc] = 1;
                        ++fc_cnt;
                    }
                    ++k; // writing a closing parenthesis, bp is already initialized to zeros
                    ++k_fc; // write a bit in first_child
                }
                vec_stack.push(x);
                bp[k++] = 1; // writing an opening parenthesis
            }
            r_sum += r; r = lcp_buf.load_next_block();
        }
    }
    while (!vec_stack.empty()) {
        if (vec_stack.pop()) {
            bp_fc[k_fc] = 1;
            ++fc_cnt;
        }
        // writing a closing parenthesis in bp, not necessary as bp is initalized with zeros
        ++k;
        ++k_fc;
    }
//	assert( k == 2*vec.size() );
    return fc_cnt;
}