37  DCHECK_GE(num_elements, 0);
 
   38  element_.assign(num_elements, -1);
 
   39  index_of_.assign(num_elements, -1);
 
   40  for (
int i = 0; i < num_elements; ++i) {
 
   44  part_of_.assign(num_elements, 0);
 
   46  for (
int i = 0; i < num_elements; ++i) fprint ^= FprintOfInt32(i);
 
   47  part_.push_back(Part(0, num_elements,
 
 
   53    const std::vector<int>& initial_part_of_element) {
 
   54  if (initial_part_of_element.empty()) 
return;
 
   55  part_of_ = initial_part_of_element;
 
   56  const int n = part_of_.size();
 
   57  const int num_parts = 1 + *std::max_element(part_of_.begin(), part_of_.end());
 
   58  DCHECK_EQ(0, *std::min_element(part_of_.begin(), part_of_.end()));
 
   59  part_.resize(num_parts);
 
   62  for (
int i = 0; i < n; ++i) part_[part_of_[i]].fprint ^= FprintOfInt32(i);
 
   67  for (
int p = 0; p < num_parts; ++p) {
 
   68    part_[p].end_index = 0;  
 
   69    part_[p].parent_part = p;
 
   71  for (
const int p : part_of_) ++part_[p].end_index;  
 
   72  int sum_part_sizes = 0;
 
   73  for (
int p = 0; p < num_parts; ++p) {
 
   74    part_[p].start_index = sum_part_sizes;
 
   75    sum_part_sizes += part_[p].end_index;  
 
   81  for (Part& part : part_) part.end_index = part.start_index;
 
   82  element_.assign(n, -1);
 
   83  index_of_.assign(n, -1);
 
   84  for (
int element = 0; element < n; ++element) {
 
   85    Part* 
const part = &part_[part_of_[element]];
 
   86    element_[part->end_index] = element;
 
   87    index_of_[element] = part->end_index;
 
   94  DCHECK_EQ(0, part_[0].start_index);
 
   96  for (
int p = 1; p < 
NumParts(); ++p) {
 
   97    DCHECK_EQ(part_[p - 1].end_index, part_[p].start_index);
 
 
  104  tmp_counter_of_part_.resize(
NumParts(), 0);
 
  106  tmp_affected_parts_.clear();
 
  107  for (
const int element : distinguished_subset) {
 
  108    DCHECK_GE(element, 0);
 
  110    const int part = part_of_[element];
 
  111    const int num_distinguished_elements_in_part = ++tmp_counter_of_part_[part];
 
  113    if (num_distinguished_elements_in_part == 1) {
 
  115      tmp_affected_parts_.push_back(part);
 
  118    const int old_index = index_of_[element];
 
  119    const int new_index =
 
  120        part_[part].end_index - num_distinguished_elements_in_part;
 
  121    DCHECK_GE(new_index, old_index)
 
  122        << 
"Duplicate element given to Refine(): " << element;
 
  124    index_of_[element] = new_index;
 
  125    index_of_[element_[new_index]] = old_index;
 
  126    std::swap(element_[old_index], element_[new_index]);
 
  132  std::sort(tmp_affected_parts_.begin(), tmp_affected_parts_.end());
 
  136  for (
const int part : tmp_affected_parts_) {
 
  137    const int start_index = part_[part].start_index;
 
  138    const int end_index = part_[part].end_index;
 
  139    const int split_index = end_index - tmp_counter_of_part_[part];
 
  140    tmp_counter_of_part_[part] = 0;  
 
  141    DCHECK_GE(split_index, start_index);
 
  142    DCHECK_LT(split_index, end_index);
 
  145    if (split_index == start_index) 
continue;
 
  148    uint64_t new_fprint = 0;
 
  149    for (
int i = split_index; i < end_index; ++i) {
 
  150      new_fprint ^= FprintOfInt32(element_[i]);
 
  156    part_[part].end_index = split_index;
 
  157    part_[part].fprint ^= new_fprint;
 
  158    part_.push_back(Part( split_index,  end_index,
 
  161      part_of_[element] = new_part;
 
 
  167  DCHECK_GE(
NumParts(), original_num_parts);
 
  168  DCHECK_GE(original_num_parts, 1);
 
  169  while (
NumParts() > original_num_parts) {
 
  170    const int part_index = 
NumParts() - 1;
 
  171    const Part& part = part_[part_index];
 
  172    const int parent_part_index = part.parent_part;
 
  173    DCHECK_LT(parent_part_index, part_index) << 
"UndoRefineUntilNumPartsEqual()" 
  175                                                "'original_num_parts' too low";
 
  179      part_of_[element] = parent_part_index;
 
  181    Part* 
const parent_part = &part_[parent_part_index];
 
  182    DCHECK_EQ(part.start_index, parent_part->end_index);
 
  183    parent_part->end_index = part.end_index;
 
  184    parent_part->fprint ^= part.fprint;
 
 
  190    bool sort_parts_lexicographically)
 const {
 
  191  std::vector<std::vector<int>> parts;
 
  192  for (
int i = 0; i < 
NumParts(); ++i) {
 
  194    parts.emplace_back(iterable_part.
begin(), iterable_part.
end());
 
  195    std::sort(parts.back().begin(), parts.back().end());
 
  197  if (sort_parts_lexicographically) {
 
  198    std::sort(parts.begin(), parts.end());
 
  201  for (
const std::vector<int>& part : parts) {
 
  202    if (!out.empty()) out += 
" | ";
 
  203    out += absl::StrJoin(part, 
" ");
 
 
  209  DCHECK_GE(num_nodes, 0);
 
  210  part_size_.assign(num_nodes, 1);
 
  211  parent_.assign(num_nodes, -1);
 
  212  for (
int i = 0; i < num_nodes; ++i) parent_[i] = i;
 
  213  tmp_part_bit_.assign(num_nodes, 
false);
 
 
  249  int num_nodes_kept = 0;
 
  250  for (
const int node : *nodes) {
 
  252    if (!tmp_part_bit_[representative]) {
 
  253      tmp_part_bit_[representative] = 
true;
 
  254      (*nodes)[num_nodes_kept++] = node;
 
  257  nodes->resize(num_nodes_kept);
 
  261  for (
const int node : *nodes) tmp_part_bit_[
GetRoot(node)] = 
false;
 
 
  280  std::vector<std::vector<int>> sorted_parts(
NumNodes());
 
  281  for (
int i = 0; i < 
NumNodes(); ++i) {
 
  284  for (std::vector<int>& part : sorted_parts) {
 
  285    std::sort(part.begin(), part.end());
 
  287  std::sort(sorted_parts.begin(), sorted_parts.end());
 
  291  for (
const std::vector<int>& part : sorted_parts) {
 
  292    if (!out.empty()) out += 
" | ";
 
  293    out += absl::StrJoin(part, 
" ");
 
 
  299    absl::Span<const int> distinguished_subset) {
 
  302  temp_to_clean_.clear();
 
  303  std::vector<int>& local_sizes = temp_data_by_part_;
 
  304  local_sizes.resize(size_of_part_.size(), 0);
 
  305  for (
const int element : distinguished_subset) {
 
  306    const int part = part_of_[element];
 
  307    if (local_sizes[part] == 0) temp_to_clean_.push_back(part);
 
  313  for (
const int part : temp_to_clean_) {
 
  314    if (local_sizes[part] == size_of_part_[part]) {
 
  316      local_sizes[part] = 0;
 
  320    const int new_part_index = size_of_part_.size();
 
  321    size_of_part_[part] -= local_sizes[part];
 
  322    size_of_part_.push_back(local_sizes[part]);
 
  323    local_sizes[part] = new_part_index;
 
  328  for (
const int element : distinguished_subset) {
 
  329    const int new_part = local_sizes[part_of_[element]];
 
  330    if (new_part != 0) part_of_[element] = new_part;
 
  334  for (
const int part : temp_to_clean_) {
 
  335    local_sizes[part] = 0;