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

#include <cstring>
#include <iostream>
#include <memory>
#include <string>

/**
@note prime number and less than 1,000,000
*/
constexpr int max_size() { return 1000003; }

constexpr int null_val() { return -1; }

class dictionary {
public:
  dictionary() : _data(std::make_unique<int[]>(max_size())) {
    for (int i = 0; i < max_size(); ++i) {
      _data[i] = null_val();
    }
  }

  void insert(const std::string &str) {
    return insert(str2key(str), 0);
    return;
  }

  bool find(const std::string &str) { return find(str2key(str), 0); }

private:
  int str2int(const char ch) {
    if (ch == 'A') {
      return 1;
    }
    if (ch == 'C') {
      return 2;
    }
    if (ch == 'G') {
      return 3;
    }
    if (ch == 'T') {
      return 4;
    }
    return 0;
  }

  int pow5(int exp) const {
    if (exp == 0) {
      return 1;
    }
    return 5 * pow5(exp - 1);
  }

  int str2key(const std::string &str) {
    int sum = 0;

    for (std::size_t i = 0; i < str.size(); ++i) {
      sum += str2int(str[i]) * pow5(i);
    }

    return sum;
  }

  int base_hash(const int key) const { return key % max_size(); }

  int collision_hash(const int key) const {
    constexpr int modulo = max_size() + 1;
    return 1 + key % modulo;
  }

  int create_hash(const int key, const int r) const {
    const int base = base_hash(key);
    const int collision = collision_hash(key);
    const int h = (base + r * collision) % max_size();
    return h;
  }

  void insert(const int key, const int r) {
    const int h = create_hash(key, r);
    if (is_empty(h)) {
      _data[h] = key;
      return;
    }
    if (_data[h] == key) {
      return;
    }

    insert(key, r + 1);
    return;
  }

  bool find(const int key, const int r) const {
    const int h = create_hash(key, r);
    if (is_empty(h)) {
      return false;
    }
    if (_data[h] == key) {
      return true;
    }

    return find(key, r + 1);
  }

  bool is_empty(const int idx) const { return _data[idx] == null_val(); }

private:
  std::unique_ptr<int[]> _data;
};

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  int n;
  std::cin >> n;
  std::cin.ignore();

  dictionary dict;
  std::string buf;
  for (int i = 0; i < n; ++i) {
    getline(std::cin, buf);
    if (buf.front() == 'i') {
      static const std::size_t size = strlen("insert ");
      const std::string val = buf.substr(size, buf.size() - size);
      dict.insert(val);
    } else {
      static const std::size_t size = strlen("find ");
      const std::string val = buf.substr(size, buf.size() - size);
      if (dict.find(val)) {
        std::cout << "yes" << std::endl;
      } else {
        std::cout << "no" << std::endl;
      }
    }
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <cstring>
#include <iostream>
#include <memory>
#include <string>

/**
@note prime number and less than 1,000,000
*/
constexpr int max_size() { return 1046527; }

class dictionary {
public:
  dictionary() : _data(std::make_unique<std::string[]>(max_size())) {}

  void insert(const std::string &str) {
    return insert(str, str2key(str), 0);
    return;
  }

  bool find(const std::string &str) { return find(str, str2key(str), 0); }

private:
  int str2int(const char ch) {
    if (ch == 'A') {
      return 1;
    }
    if (ch == 'C') {
      return 2;
    }
    if (ch == 'G') {
      return 3;
    }
    if (ch == 'T') {
      return 4;
    }
    return 0;
  }

  int str2key(const std::string &str) {
    int sum = 0;

    for (std::size_t i = 0; i < str.size(); ++i) {
      sum += str2int(str[i]);
    }

    return sum;
  }

  int base_hash(const int key) const { return key % max_size(); }

  int collision_hash(const int key) const {
    constexpr int modulo = max_size() + 1;
    return 1 + key % modulo;
  }

  int create_hash(const int key, const int r) const {
    const int base = base_hash(key);
    const int collision = collision_hash(key);
    const int h = (base + r * collision) % max_size();
    return h;
  }

  void insert(const std::string &str, const int key, const int r) {
    const int h = create_hash(key, r);
    if (_data[h].empty()) {
      _data[h] = str;
      return;
    }
    if (_data[h] == str) {
      return;
    }

    insert(str, key, r + 1);
    return;
  }

  bool find(const std::string &str, const int key, const int r) const {
    const int h = create_hash(key, r);
    if (_data[h].empty()) {
      return false;
    }
    if (_data[h] == str) {
      return true;
    }

    return find(str, key, r + 1);
  }

private:
  std::unique_ptr<std::string[]> _data;
};

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  int n;
  std::cin >> n;
  std::cin.ignore();

  dictionary dict;
  std::string buf;
  for (int i = 0; i < n; ++i) {
    getline(std::cin, buf);
    if (buf.front() == 'i') {
      static const std::size_t size = strlen("insert ");
      const std::string val = buf.substr(size, buf.size() - size);
      dict.insert(val);
    } else {
      static const std::size_t size = strlen("find ");
      const std::string val = buf.substr(size, buf.size() - size);
      if (dict.find(val)) {
        std::cout << "yes" << std::endl;
      } else {
        std::cout << "no" << std::endl;
      }
    }
  }

  return 0;
}