Problem p00121 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <cassert>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
template <typename K, typename V> class AVLTree {
  enum class Bias : char { L = 'L', Eq = 'E', R = 'R' };
  struct Tree {
    V val;
    Tree *left{nullptr}, *right{nullptr};
    K key;
    Bias bias{Bias::Eq};
    Tree(const K &, const V &);
    ~Tree();
    bool has_key(const K &) const;
    V &operator[](const K &);
    Tree *find_leften() const;
    int depth() const;
  };

public:
  AVLTree();
  ~AVLTree();
  void insert(const K &, const V &);
  void erase(const K &);
  bool has_key(const K &) const;
  size_t size() const;
  int depth() const;
  V &operator[](const K &);

private:
  int factor_size{0};
  Tree *tree{nullptr};
  bool single_right(Tree *&top);
  bool single_left(Tree *&top);
  void turn_right(Tree *&top);
  void turn_left(Tree *&top);
  bool double_right(Tree *&top);
  bool double_left(Tree *&top);
  bool insert_by_key(const K &, const V &, Tree *&);
  bool increase_right(Tree *&);
  bool increase_left(Tree *&);
  bool reduce_right(Tree *&);
  bool reduce_left(Tree *&);
  bool erase_by_key(const K &, Tree *&);
  bool void_leften(Tree *&);
  void move_position(Tree *&from, Tree *&to);
};

template <typename K, typename V> int AVLTree<K, V>::depth() const {
  if (factor_size == 0)
    return 0;
  else
    return tree->depth();
}
template <typename K, typename V> int AVLTree<K, V>::Tree::depth() const {
  if (left && right) {
    switch (bias) {
    case Bias::Eq:
    case Bias::R:
      return right->depth() + 1;
    case Bias::L:
      return left->depth() + 1;
    }
  } else {
    if (bias == Bias::Eq)
      return 1;
    else
      return 2;
  }
}

template <typename K, typename V> AVLTree<K, V>::AVLTree(){};
template <typename K, typename V> AVLTree<K, V>::~AVLTree() { delete tree; };

template <typename K, typename V>
void AVLTree<K, V>::insert(const K &k, const V &v) {
  if (factor_size++ > 0)
    insert_by_key(k, v, tree);
  else
    tree = new Tree(k, v);
}
template <typename K, typename V> void AVLTree<K, V>::erase(const K &k) {
  assert(factor_size > 0 && tree->has_key(k));
  erase_by_key(k, tree);
  --factor_size;
}
template <typename K, typename V>
bool AVLTree<K, V>::has_key(const K &k) const {
  return factor_size > 0 && tree->has_key(k);
}
template <typename K, typename V> V &AVLTree<K, V>::operator[](const K &k) {
  assert(factor_size > 0 && tree->has_key(k));
  return tree->operator[](k);
}
template <typename K, typename V> size_t AVLTree<K, V>::size() const {
  return factor_size;
}

template <typename K, typename V>
AVLTree<K, V>::Tree::Tree(const K &k, const V &v) : key{k}, val{v} {};
template <typename K, typename V> AVLTree<K, V>::Tree::~Tree() {
  delete left;
  delete right;
}
template <typename K, typename V>
bool AVLTree<K, V>::Tree::has_key(const K &k) const {
  if (k == key)
    return true;
  else if (k < key && left)
    return left->has_key(k);
  else if (k > key && right)
    return right->has_key(k);
  else
    return false;
}
template <typename K, typename V>
V &AVLTree<K, V>::Tree::operator[](const K &k) {
  if (k == key)
    return val;
  else if (k < key && left)
    return left->operator[](k);
  else if (k > key && right)
    return right->operator[](k);
  else
    assert(false);
}
template <typename K, typename V>
typename AVLTree<K, V>::Tree *AVLTree<K, V>::Tree::find_leften() const {
  if (left)
    return left->find_leften();
  else
    return this;
}

template <typename K, typename V> void AVLTree<K, V>::turn_right(Tree *&top) {
  auto const old_left = top->left;
  top->left = top->left->right;
  old_left->right = top;
  top = old_left;
};
template <typename K, typename V> void AVLTree<K, V>::turn_left(Tree *&top) {
  auto const old_right = top->right;
  top->right = top->right->left;
  old_right->left = top;
  top = old_right;
};

template <typename K, typename V> bool AVLTree<K, V>::single_right(Tree *&top) {
  turn_right(top);
  switch (top->bias) {
  case Bias::L:
    top->bias = Bias::Eq;
    top->right->bias = Bias::Eq;
    return false;
  case Bias::Eq:
    top->bias = Bias::R;
    top->right->bias = Bias::L;
    return true;
  default:
    assert(false);
  }
}
template <typename K, typename V> bool AVLTree<K, V>::single_left(Tree *&top) {
  turn_left(top);
  switch (top->bias) {
  case Bias::R:
    top->bias = Bias::Eq;
    top->left->bias = Bias::Eq;
    return false;
  case Bias::Eq:
    top->bias = Bias::L;
    top->left->bias = Bias::R;
    return true;
  default:
    assert(false);
  }
}
template <typename K, typename V> bool AVLTree<K, V>::double_right(Tree *&top) {
  turn_left(top->left);
  turn_right(top);
  switch (top->bias) {
  case Bias::Eq:
    top->bias = Bias::Eq;
    top->left->bias = Bias::Eq;
    top->right->bias = Bias::Eq;
    return false;
  case Bias::R:
    top->bias = Bias::Eq;
    top->left->bias = Bias::L;
    top->right->bias = Bias::Eq;
    return false;
  case Bias::L:
    top->bias = Bias::Eq;
    top->left->bias = Bias::Eq;
    top->right->bias = Bias::R;
    return false;
  default:
    assert(false);
  }
};
template <typename K, typename V> bool AVLTree<K, V>::double_left(Tree *&top) {
  turn_right(top->right);
  turn_left(top);
  switch (top->bias) {
  case Bias::Eq:
    top->bias = Bias::Eq;
    top->left->bias = Bias::Eq;
    top->right->bias = Bias::Eq;
    return false;
  case Bias::L:
    top->bias = Bias::Eq;
    top->left->bias = Bias::Eq;
    top->right->bias = Bias::R;
    return false;
  case Bias::R:
    top->bias = Bias::Eq;
    top->left->bias = Bias::L;
    top->right->bias = Bias::Eq;
    return false;
  default:
    assert(false);
  }
};
template <typename K, typename V>
bool AVLTree<K, V>::insert_by_key(const K &k, const V &v, Tree *&top) {
  assert(top->key != k);
  if (k < (top->key)) {
    if (!top->left || insert_by_key(k, v, top->left)) {
      if (!top->left)
        top->left = new Tree(k, v);
      return increase_left(top);
    } else
      return false;
  } else {
    if (!top->right || insert_by_key(k, v, top->right)) {
      if (!top->right)
        top->right = new Tree(k, v);
      return increase_right(top);
    } else
      return false;
  }
}
template <typename K, typename V>
bool AVLTree<K, V>::increase_right(Tree *&top) {
  switch (top->bias) {
  case Bias::R:
    switch (top->right->bias) {
    case Bias::L:
      return double_left(top);
    default:
      return single_left(top);
    }
  case Bias::Eq:
    top->bias = Bias::R;
    return true;
  case Bias::L:
    top->bias = Bias::Eq;
    return false;
  default:
    assert(false);
  }
}
template <typename K, typename V>
bool AVLTree<K, V>::increase_left(Tree *&top) {
  switch (top->bias) {
  case Bias::L:
    switch (top->left->bias) {
    case Bias::R:
      return double_right(top);
    default:
      return single_right(top);
    }
  case Bias::Eq:
    top->bias = Bias::L;
    return true;
  case Bias::R:
    top->bias = Bias::Eq;
    return false;
  default:
    assert(false);
  }
}
template <typename K, typename V> bool AVLTree<K, V>::reduce_right(Tree *&top) {
  return !increase_left(top);
}
template <typename K, typename V> bool AVLTree<K, V>::reduce_left(Tree *&top) {
  return !increase_right(top);
}
template <typename K, typename V>
bool AVLTree<K, V>::erase_by_key(const K &k, Tree *&top) {
  if (k == top->key) {
    if (top->right) {
      auto leften = top->right->find_leften();
      auto flag = void_leften(top->right);
      assert(!leften->left);
      move_position(leften, top);
      if (flag)
        return reduce_right(top);
      else
        return false;
    } else {
      if (top->left)
        move_position(top->left, top);
      else {
        delete top;
        top = nullptr;
      }
      return true;
    }
  } else if (k < top->key) {
    assert(top->left);
    if (erase_by_key(k, top->left))
      return reduce_left(top);
    else
      return false;
  } else {
    assert(top->right);
    if (erase_by_key(k, top->right))
      return reduce_right(top);
    else
      return false;
  }
}
template <typename K, typename V> bool AVLTree<K, V>::void_leften(Tree *&top) {
  if (top->left) {
    if (void_leften(top->left))
      return reduce_left(top);
    else
      return false;
  } else {
    if (top->right)
      top = top->right;
    else
      top = nullptr;
    return true;
  }
}
template <typename K, typename V>
void AVLTree<K, V>::move_position(Tree *&from, Tree *&to) {
  from->left = to->left;
  from->right = to->right;
  from->bias = to->bias;
  auto temp = to;
  to = from;
  temp->left = nullptr;
  temp->right = nullptr;
  delete temp;
}

static const std::vector<std::vector<int>> swapable{
    {1, 4}, {0, 2, 5}, {1, 3, 6}, {2, 7}, {0, 5}, {1, 4, 6}, {2, 5, 7}, {3, 6}};
int exponent(const int &e) {
  if (e == 0)
    return 1;
  else
    return exponent(e - 1) * 10;
}

inline int swap(const int &state, const int &zero, const int &to) {
  auto to_digit = state / exponent(to) % 10;
  return state - to_digit * exponent(to) + to_digit * exponent(zero);
}

void cul_foward(AVLTree<int, int> &memo,
                std::queue<std::pair<int, int>> &suspend) {
  std::pair<int, int> state;
  int swaped;
  int count = 1;
  while (suspend.size() != 0) {
    for (auto i = suspend.size(); i > 0; --i) {
      state = suspend.front();
      suspend.pop();
      for (const auto &tos : swapable[state.second]) {
        swaped = swap(state.first, state.second, tos);
        if (!memo.has_key(swaped)) {
          memo.insert(swaped, count);
          suspend.push(std::make_pair(swaped, tos));
        }
      }
    }
    ++count;
  }
}
int toi(const std::string &str, const int &n = 0) {
  auto idx = str.find(' ');
  if (idx == std::string::npos) {
    return n * 10 + std::stoi(str);
  } else {
    return toi(str.substr(idx + 1), n * 10 + std::stoi(str.substr(0, idx)));
  }
}
int main() {
  AVLTree<int, int> memo;
  std::queue<std::pair<int, int>> queue;
  memo.insert(1234567, 0);
  queue.push(std::make_pair(1234567, 7));
  cul_foward(memo, queue);
  std::string str;
  int state;
  while (std::getline(std::cin, str)) {
    state = toi(str);
    assert(memo.has_key(state));
    std::cout << memo[state] << std::endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <chrono>
#include <iostream>
#include <queue>
#include <vector>
static const std::vector<int> fractional{1, 1, 2, 6, 24, 120, 720, 5040};
void permutation_eight(std::vector<int> &vector, std::vector<bool> &memo,
                       const int &state = 0, const int &digit = 7,
                       const int &id = 0) {
  if (digit < 0) {
    vector.at(id) = state;
  } else {
    auto vias = 0;
    for (auto i = 0; i < 8; ++i) {
      if (memo.at(i)) {
        memo.at(i) = false;
        permutation_eight(vector, memo, state * 10 + i, digit - 1, id + vias);
        memo.at(i) = true;
        vias += fractional.at(digit);
      }
    }
  }
}
std::vector<int> permutation() {
  std::vector<int> vector(fractional.at(7) * 8);
  std::vector<bool> memo(8, true);
  permutation_eight(vector, memo);
  return vector;
}
static const std::vector<int> perm{permutation()};
int coord(int state, int d) {
  int res = 10;
  for (; d > 0; --d) {
    res *= 10;
    state /= 10;
  }
  return (res + 1) * (state % 10);
}
static const std::vector<int> order{1,     10,     100,     1000,
                                    10000, 100000, 1000000, 10000000};
int swap(const int &state, const int &zero, int target) {
  target = coord(state, target);
  return state - target / 10 + (target % 10) * order.at(zero);
}
int zero_digit(const int &n, const int &z = 0) {
  if (n % 10 == 0) {
    return z;
  } else {
    return zero_digit(n / 10, z + 1);
  }
}
int bin_search(const int &state, const int &left = 0,
               const int &right = 40319) {
  if (left == right) {
    return right;
  } else {
    auto mid = (left + right) >> 1;
    if (perm.at(mid) >= state) {
      return bin_search(state, left, mid);
    } else {
      return bin_search(state, mid + 1, right);
    }
  }
}
bool is_not_passed(const int &state, const std::vector<bool> &memo) {
  return !memo.at(bin_search(state));
}
void renew_memo(const int &state, std::vector<bool> &memo) {
  memo.at(bin_search(state)) = true;
}
int wfs(int state) {
  int i = 0;
  std::vector<std::queue<int>> queue(2, std::queue<int>());
  queue.at(i).push(state);
  std::vector<bool> memo(40320, false);
  renew_memo(state, memo);
  while (is_not_passed(1234567, memo)) {
    for (; queue.at(i % 2).size() != 0; queue.at(i % 2).pop()) {
      state = queue.at(i % 2).front();
      auto zero = zero_digit(state);
      auto left = swap(state, zero, zero + 1);
      auto right = swap(state, zero, zero - 1);
      auto up = swap(state, zero, (zero + 4) % 8);
      if ((zero % 4 != 3) && is_not_passed(left, memo)) {
        renew_memo(left, memo);
        queue.at((i + 1) % 2).push(left);
      }
      if ((zero % 4 != 0) && is_not_passed(right, memo)) {
        renew_memo(right, memo);
        queue.at((i + 1) % 2).push(right);
      }
      if (is_not_passed(up, memo)) {
        renew_memo(up, memo);
        queue.at((i + 1) % 2).push(up);
      }
    }
    ++i;
  }
  return i;
}
int main() {
  int state = 0;
  while (std::cin >> state) {
    int a;
    for (auto i = 0; i < 7; ++i) {
      std::cin >> a;
      state = state * 10 + a;
    }
    // auto start = std::chrono::system_clock::now();
    std::cout << wfs(state) << '\\n';
    // auto end = std::chrono::system_clock::now();
    // std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(end -
    // start).count();
  }
  return 0;
}