kyopro-lib

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:heavy_check_mark: Binomial heap
(Mylib/DataStructure/Heap/binomial_heap.cpp)

Operations

Requirements

Notes

Problems

References

Verified with

Code

#pragma once
#include <array>
#include <cassert>
#include <functional>
#include <vector>

namespace haar_lib {
  template <typename T, typename Compare = std::less<T>>
  class binomial_heap {
  public:
    using value_type = T;

  private:
    struct node {
      T value;
      std::vector<node *> children;
      node(T value) : value(value) {}
    };

    constexpr static int MAX = 31;

    std::array<node *, MAX> roots_;
    Compare compare_;
    int top_index_ = -1;
    int heap_size_ = 0;

    node *merge(node *a, node *b) {
      if (compare_(a->value, b->value)) std::swap(a, b);
      a->children.push_back(b);
      return a;
    }

    template <typename Container>
    void meld(Container c) {
      node *s = nullptr;

      for (int i = 0; i < MAX; ++i) {
        std::vector<node *> temp;
        if (s) {
          temp.push_back(s);
          s = nullptr;
        }
        if (roots_[i]) {
          temp.push_back(roots_[i]);
          roots_[i] = nullptr;
        }
        if (i < (int) c.size() and c[i]) {
          temp.push_back(c[i]);
          c[i] = nullptr;
        }

        switch (temp.size()) {
          case 1: roots_[i] = temp[0]; break;
          case 2: s = merge(temp[0], temp[1]); break;
          case 3:
            roots_[i] = temp[0];
            s         = merge(temp[1], temp[2]);
            break;
        }
      }

      top_index_ = -1;
      for (int i = 0; i < MAX; ++i) {
        if (roots_[i]) {
          if (top_index_ == -1 or compare_(roots_[top_index_]->value, roots_[i]->value)) {
            top_index_ = i;
          }
        }
      }
    }

  public:
    binomial_heap() {
      roots_.fill(nullptr);
      compare_ = Compare();
    }

    int size() const {
      return heap_size_;
    }

    bool empty() const {
      return heap_size_ == 0;
    }

    void push(const T &value) {
      heap_size_ += 1;
      node *t = new node(value);

      meld(std::vector<node *>({t}));
    }

    const T &top() const {
      return roots_[top_index_]->value;
    }

    void pop() {
      heap_size_ -= 1;

      node *t            = roots_[top_index_];
      roots_[top_index_] = nullptr;
      meld(t->children);

      delete t;
    }

    void meld(binomial_heap &rhs) {
      heap_size_ += rhs.heap_size_;
      meld(rhs.roots_);
      rhs.roots_.fill(nullptr);
    }
  };
}  // namespace haar_lib
#line 2 "Mylib/DataStructure/Heap/binomial_heap.cpp"
#include <array>
#include <cassert>
#include <functional>
#include <vector>

namespace haar_lib {
  template <typename T, typename Compare = std::less<T>>
  class binomial_heap {
  public:
    using value_type = T;

  private:
    struct node {
      T value;
      std::vector<node *> children;
      node(T value) : value(value) {}
    };

    constexpr static int MAX = 31;

    std::array<node *, MAX> roots_;
    Compare compare_;
    int top_index_ = -1;
    int heap_size_ = 0;

    node *merge(node *a, node *b) {
      if (compare_(a->value, b->value)) std::swap(a, b);
      a->children.push_back(b);
      return a;
    }

    template <typename Container>
    void meld(Container c) {
      node *s = nullptr;

      for (int i = 0; i < MAX; ++i) {
        std::vector<node *> temp;
        if (s) {
          temp.push_back(s);
          s = nullptr;
        }
        if (roots_[i]) {
          temp.push_back(roots_[i]);
          roots_[i] = nullptr;
        }
        if (i < (int) c.size() and c[i]) {
          temp.push_back(c[i]);
          c[i] = nullptr;
        }

        switch (temp.size()) {
          case 1: roots_[i] = temp[0]; break;
          case 2: s = merge(temp[0], temp[1]); break;
          case 3:
            roots_[i] = temp[0];
            s         = merge(temp[1], temp[2]);
            break;
        }
      }

      top_index_ = -1;
      for (int i = 0; i < MAX; ++i) {
        if (roots_[i]) {
          if (top_index_ == -1 or compare_(roots_[top_index_]->value, roots_[i]->value)) {
            top_index_ = i;
          }
        }
      }
    }

  public:
    binomial_heap() {
      roots_.fill(nullptr);
      compare_ = Compare();
    }

    int size() const {
      return heap_size_;
    }

    bool empty() const {
      return heap_size_ == 0;
    }

    void push(const T &value) {
      heap_size_ += 1;
      node *t = new node(value);

      meld(std::vector<node *>({t}));
    }

    const T &top() const {
      return roots_[top_index_]->value;
    }

    void pop() {
      heap_size_ -= 1;

      node *t            = roots_[top_index_];
      roots_[top_index_] = nullptr;
      meld(t->children);

      delete t;
    }

    void meld(binomial_heap &rhs) {
      heap_size_ += rhs.heap_size_;
      meld(rhs.roots_);
      rhs.roots_.fill(nullptr);
    }
  };
}  // namespace haar_lib
Back to top page