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

#include <bits/stdc++.h>
#define ll long long
#define rep(i, from, to) for (int i = from; i < to; ++i)
using namespace std;

static const int M = 1046597;
static const int L = 14;
char T[M][L];
char com[6], word[L];

int getChar(char ch) {
  if (ch == 'A') {
    return 1;
  } else if (ch == 'C') {
    return 2;
  } else if (ch == 'G') {
    return 3;
  } else {
    return 4;
  }
}

int getKey(char str[]) {
  int key = 0;
  rep(i, 0, (int)strlen(str)) {
    key += getChar(str[i]);
    key *= 5; // 左シフト(5進数)
  }
  return key;
}

int hash1(int key) { return key % M; }

// Mとh2は互いに素に
int hash2(int key) {
  // 素数Mより小さい数はみなMと互いに素
  // h2の周期はM未満であればなんでも可
  // 1を加えるのはkey%(M-1)==0のときにずれなくなるのを防ぐため
  // この関数は1 ~ M-1の間の値をとる
  return 1 + (key % (M - 1));
}

bool insert(char str[]) {
  ll key, h;
  key = getKey(str);
  ll h1 = hash1(key), h2 = hash2(key);
  for (ll i = 0;; ++i) {
    h = (h1 + i * h2) % M;
    if (strcmp(T[h], str) == 0) {
      return false; // すでに格納済
    } else if (strlen(T[h]) == 0) {
      strcpy(T[h], str);
      return true;
    }
  }
  return false;
}

bool find(char str[]) {
  ll key, h;
  key = getKey(str);
  ll h1 = hash1(key), h2 = hash2(key);
  for (ll i = 0;; ++i) {
    h = (h1 + i * h2) % M;
    if (strcmp(T[h], str) == 0) {
      return true;
    } else if (strlen(T[h]) == 0) {
      return false;
    }
  }
  return false;
}

void solve() {
  rep(i, 0, M) {
    T[i][0] = '\\0'; // すべて空文字列で初期化
  }
  int n;
  scanf("%d", &n);
  rep(i, 0, n) {
    scanf("%s %s", com, word);
    if (com[0] == 'i') {
      insert(word);
    } else {
      if (find(word)) {
        printf("yes\\n");
      } else {
        printf("no\\n");
      }
    }
  }
}

int main() {
  solve();
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define ll long long
#define rep(i, from, to) for (int i = from; i < to; ++i)
using namespace std;

static const int M = 1046597;
static const int L = 14;
char T[M][L];
char com[6], word[L];

int getChar(char ch) {
  if (ch == 'A') {
    return 1;
  } else if (ch == 'C') {
    return 2;
  } else if (ch == 'G') {
    return 3;
  } else {
    return 4;
  }
}

ll getKey(char str[]) {
  ll key = 0;
  rep(i, 0, (int)strlen(str)) {
    key += getChar(str[i]);
    key *= 5; // 左シフト(5進数)
  }
  return key;
}

int hash1(int key) { return key % M; }

// Mとh2は互いに素に
int hash2(int key) {
  // 素数Mより小さい数はみなMと互いに素
  // h2の周期はM未満であればなんでも可
  // 1を加えるのはkey%(M-1)==0のときにずれなくなるのを防ぐため
  // この関数は1 ~ M-1の間の値をとる
  return 1 + (key % (M - 1));
}

bool insert(char str[]) {
  ll key, h;
  int h1 = hash1(key), h2 = hash2(key);
  key = getKey(str);
  for (ll i = 0;; ++i) {
    h = (h1 + i * h2) % M;
    if (strcmp(T[h], str) == 0) {
      return false; // すでに格納済
    } else if (strlen(T[h]) == 0) {
      strcpy(T[h], str);
      return true;
    }
  }
  return false;
}

bool find(char str[]) {
  ll key, h;
  int h1 = hash1(key), h2 = hash2(key);
  key = getKey(str);
  for (ll i = 0;; ++i) {
    h = (h1 + i * h2) % M;
    if (strcmp(T[h], str) == 0) {
      return true;
    } else if (strlen(T[h]) == 0) {
      return false;
    }
  }
  return false;
}

void solve() {
  rep(i, 0, M) {
    T[i][0] = '\\0'; // すべて空文字列で初期化
  }
  int n;
  scanf("%d", &n);
  rep(i, 0, n) {
    scanf("%s %s", com, word);
    if (com[0] == 'i') {
      insert(word);
    } else {
      if (find(word)) {
        printf("yes\\n");
      } else {
        printf("no\\n");
      }
    }
  }
}

int main() {
  solve();
  return 0;
}